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)
{
@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 (backtrace.len() <= backtraces_to_ignore) return false;
(void)io::stderr().print("\nERROR: '");
@@ -391,13 +391,32 @@ SignalFunction old_segmentation_fault;
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();
}
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

View File

@@ -37,8 +37,7 @@ def CompareFunction = fn int(void*, void*);
def JmpBuf = uptr[$$JMP_BUF_SIZE];
def Fd = CInt;
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 SIGINT = 2;

View File

@@ -3,3 +3,36 @@ module libc @if(env::POSIX);
def Pid_t = int;
def Uid_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
{
@stack_mem(1024; Allocator* mem)
@pool(using)
{
if (buffer)
{
SubProcess process = process::create({ "atos",
"-o", execpath, "-arch", env::AARCH64 ? "arm64" : "x86_64", "-l",
string::printf("%p", load_address, .using = mem),
string::printf("%p", buffer, .using = mem),
string::tprintf("%p", load_address),
string::tprintf("%p", buffer),
"-fullPath" })!;
process.join()!;
char[4096] buf;
usz len = process.read_stdout(&buf, buf.len)!;
char* buf = tmalloc(1024);
usz len = process.read_stdout(buf, 1024)!;
String s = (String)buf[:len - 1];
String[] parts = s.split(" ", .using = mem);
String[] parts = s.tsplit(" ");
if (parts.len == 4)
{
String[] path_parts = parts[3].split(":", .using = mem);
String[] path_parts = parts[3].tsplit(":");
return {
.offset = (uptr)buffer,
.function = parts[0].copy(using),
@@ -151,12 +151,11 @@ fn BacktraceList! backtrace_load(Allocator* using = mem::heap())
}
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++)
{
char[1024] fname;
void* buffer = bt_buffer[i];
Backtrace trace = backtrace_load_element(execpath, buffer, load_addr, .using = using)!;
list.append(trace);

View File

@@ -749,6 +749,7 @@ static void llvm_codegen_setup()
attribute_id.reassoc = lookup_attribute("reassoc");
attribute_id.sext = lookup_attribute("signext");
attribute_id.sret = lookup_attribute("sret");
attribute_id.ssp = lookup_attribute("ssp");
attribute_id.target_features = lookup_attribute("target-features");
attribute_id.uwtable = lookup_attribute("uwtable");
attribute_id.writeonly = lookup_attribute("writeonly");
@@ -1005,6 +1006,7 @@ void llvm_append_function_attributes(GenContext *c, Decl *decl)
if (c->debug.enable_stacktrace)
{
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, "no-trapping-math", "true", -1);

View File

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

View File

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