Use regular backtrace for Mac on signals as well.

This commit is contained in:
Christoffer Lerno
2023-09-22 01:12:33 +02:00
parent c4228e08c5
commit 8dad8f2b1c
7 changed files with 70 additions and 17 deletions

View File

@@ -91,9 +91,9 @@ struct CallstackElement
fn bool print_backtrace(String message, int backtraces_to_ignore) @if(env::DARWIN) fn bool print_backtrace(String message, int backtraces_to_ignore) @if(env::DARWIN)
{ {
@stack_mem(4096; Allocator *mem) @pool()
{ {
BacktraceList! backtrace = darwin::backtrace_load(mem); BacktraceList! backtrace = darwin::backtrace_load(mem::temp());
if (catch backtrace) return false; if (catch backtrace) return false;
if (backtrace.len() <= backtraces_to_ignore) return false; if (backtrace.len() <= backtraces_to_ignore) return false;
(void)io::stderr().print("\nERROR: '"); (void)io::stderr().print("\nERROR: '");
@@ -391,13 +391,32 @@ SignalFunction old_segmentation_fault;
fn void sig_bus_error(CInt i) fn void sig_bus_error(CInt i)
{ {
sig_panic("Illegal memory access."); $if !env::DARWIN:
sig_panic("Illegal memory access.");
$else
$if $defined(io::stderr) && $defined(Stream.printf):
if (!print_backtrace("Illegal memory access.", 1))
{
(void)io::stderr().printn("\nERROR: 'Illegal memory access'.");
}
$endif
$endif
$$trap(); $$trap();
} }
fn void sig_segmentation_fault(CInt i) fn void sig_segmentation_fault(CInt i)
{ {
sig_panic("Out of bounds memory access."); $if !env::DARWIN:
sig_panic("Out of bounds memory access.");
$else
$if $defined(io::stderr) && $defined(Stream.printf):
if (!print_backtrace("Out of bounds memory access.", 1))
{
(void)io::stderr().printn("\nERROR: Memory error without backtrace, possible stack overflow.");
}
$endif
$endif
$$trap();
} }
fn void install_signal_handler(CInt signal, SignalFunction func) @local fn void install_signal_handler(CInt signal, SignalFunction func) @local

View File

@@ -37,8 +37,7 @@ def CompareFunction = fn int(void*, void*);
def JmpBuf = uptr[$$JMP_BUF_SIZE]; def JmpBuf = uptr[$$JMP_BUF_SIZE];
def Fd = CInt; def Fd = CInt;
def Fpos_t = long; // TODO make sure fpos is correct on all targets. def Fpos_t = long; // TODO make sure fpos is correct on all targets.
def SignalFunction = fn void(int); def SignalFunction = fn void(CInt);
const CInt SIGHUP = 1; const CInt SIGHUP = 1;
const CInt SIGINT = 2; const CInt SIGINT = 2;

View File

@@ -3,3 +3,36 @@ module libc @if(env::POSIX);
def Pid_t = int; def Pid_t = int;
def Uid_t = uint; def Uid_t = uint;
def Gid_t = uint; def Gid_t = uint;
const CInt SA_ONSTACK = env::LINUX ? 0x08000000 : 0x0001;
const CInt SA_RESTART = env::LINUX ? 0x10000000 : 0x0002;
const CInt SA_RESETHAND = env::LINUX ? 0x80000000 : 0x0004;
const CInt SA_SIGINFO = env::LINUX ? 0x00000004 : 0x0040;
def Sigset_t = uint @if(!env::LINUX);
def Sigset_t = ulong[16] @if(env::LINUX);
def SigActionFunction = fn void(CInt, void*, void*);
struct Sigaction
{
union
{
SignalFunction sa_handler;
SigActionFunction sa_sigaction;
}
CInt sa_flags @if(env::FREEBSD);
Sigset_t sa_mask; // 128
CInt sa_flags @if(!env::FREEBSD);
void* sa_restorer @if(env::LINUX);
}
struct Stack_t
{
void* ss_sp;
usz ss_size @if(!env::LINUX);
CInt ss_flags;
usz ss_size @if(env::LINUX);
}
extern fn CInt sigaltstack(Stack_t* ss, Stack_t* old_ss);
extern fn CInt sigaction(CInt signum, Sigaction *action, Sigaction *oldaction);

View File

@@ -97,23 +97,23 @@ fn uptr! load_address() @local
fn Backtrace! backtrace_load_element(String execpath, void* buffer, void* load_address, Allocator* using = mem::heap()) @local fn Backtrace! backtrace_load_element(String execpath, void* buffer, void* load_address, Allocator* using = mem::heap()) @local
{ {
@stack_mem(1024; Allocator* mem) @pool(using)
{ {
if (buffer) if (buffer)
{ {
SubProcess process = process::create({ "atos", SubProcess process = process::create({ "atos",
"-o", execpath, "-arch", env::AARCH64 ? "arm64" : "x86_64", "-l", "-o", execpath, "-arch", env::AARCH64 ? "arm64" : "x86_64", "-l",
string::printf("%p", load_address, .using = mem), string::tprintf("%p", load_address),
string::printf("%p", buffer, .using = mem), string::tprintf("%p", buffer),
"-fullPath" })!; "-fullPath" })!;
process.join()!; process.join()!;
char[4096] buf; char* buf = tmalloc(1024);
usz len = process.read_stdout(&buf, buf.len)!; usz len = process.read_stdout(buf, 1024)!;
String s = (String)buf[:len - 1]; String s = (String)buf[:len - 1];
String[] parts = s.split(" ", .using = mem); String[] parts = s.tsplit(" ");
if (parts.len == 4) if (parts.len == 4)
{ {
String[] path_parts = parts[3].split(":", .using = mem); String[] path_parts = parts[3].tsplit(":");
return { return {
.offset = (uptr)buffer, .offset = (uptr)buffer,
.function = parts[0].copy(using), .function = parts[0].copy(using),
@@ -151,12 +151,11 @@ fn BacktraceList! backtrace_load(Allocator* using = mem::heap())
} }
list.free(); list.free();
} }
@stack_mem(256; Allocator* mem) @pool(using)
{ {
String execpath = executable_path(mem)!; String execpath = executable_path(mem::temp())!;
for (usz i = 1; i < size; i++) for (usz i = 1; i < size; i++)
{ {
char[1024] fname;
void* buffer = bt_buffer[i]; void* buffer = bt_buffer[i];
Backtrace trace = backtrace_load_element(execpath, buffer, load_addr, .using = using)!; Backtrace trace = backtrace_load_element(execpath, buffer, load_addr, .using = using)!;
list.append(trace); list.append(trace);

View File

@@ -749,6 +749,7 @@ static void llvm_codegen_setup()
attribute_id.reassoc = lookup_attribute("reassoc"); attribute_id.reassoc = lookup_attribute("reassoc");
attribute_id.sext = lookup_attribute("signext"); attribute_id.sext = lookup_attribute("signext");
attribute_id.sret = lookup_attribute("sret"); attribute_id.sret = lookup_attribute("sret");
attribute_id.ssp = lookup_attribute("ssp");
attribute_id.target_features = lookup_attribute("target-features"); attribute_id.target_features = lookup_attribute("target-features");
attribute_id.uwtable = lookup_attribute("uwtable"); attribute_id.uwtable = lookup_attribute("uwtable");
attribute_id.writeonly = lookup_attribute("writeonly"); attribute_id.writeonly = lookup_attribute("writeonly");
@@ -1005,6 +1006,7 @@ void llvm_append_function_attributes(GenContext *c, Decl *decl)
if (c->debug.enable_stacktrace) if (c->debug.enable_stacktrace)
{ {
llvm_attribute_add_string(c, function, "frame-pointer", "all", -1); llvm_attribute_add_string(c, function, "frame-pointer", "all", -1);
llvm_attribute_add(c, function, attribute_id.ssp, -1);
} }
llvm_attribute_add_string(c, function, "stack-protector-buffer-size", "8", -1); llvm_attribute_add_string(c, function, "stack-protector-buffer-size", "8", -1);
llvm_attribute_add_string(c, function, "no-trapping-math", "true", -1); llvm_attribute_add_string(c, function, "no-trapping-math", "true", -1);

View File

@@ -275,6 +275,7 @@ typedef struct
unsigned reassoc; // allow reassociateion unsigned reassoc; // allow reassociateion
unsigned sext; // sign extend unsigned sext; // sign extend
unsigned sret; // struct return pointer unsigned sret; // struct return pointer
unsigned ssp; // safe stack protection
unsigned target_features; // target-features for function compilation unsigned target_features; // target-features for function compilation
unsigned uwtable; unsigned uwtable;
unsigned writeonly; // No writes on pointer unsigned writeonly; // No writes on pointer

View File

@@ -1 +1 @@
#define COMPILER_VERSION "0.4.654" #define COMPILER_VERSION "0.4.655"