mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Linux: implement signal stacktrace using SA_SIGINFO + sigaltstack (#2653)
* Linux: implement signal stacktrace using SA_SIGINFO + sigaltstack Adds proper signal handlers for SIGSEGV/SIGBUS/SIGILL on Linux, enables backtraces from signal context, and exits with correct POSIX signal codes (128+signal). Fixes missing "signal stacktrace" support Signed-off-by: Manuel Barrio Linares <mbarriolinares@gmail.com> * defer libc::dlclose(handle); Signed-off-by: Manuel Barrio Linares <mbarriolinares@gmail.com> * fix double backtrace on panic Signed-off-by: Manuel Barrio Linares <mbarriolinares@gmail.com> * add guards for Linux X86_64 - remove comments - uncomment MContext_t for Linux AARCH64 Signed-off-by: Manuel Barrio Linares <mbarriolinares@gmail.com> * fix guards, missed in two places Signed-off-by: Manuel Barrio Linares <mbarriolinares@gmail.com> --------- Signed-off-by: Manuel Barrio Linares <mbarriolinares@gmail.com> Co-authored-by: Christoffer Lerno <christoffer@aegik.com>
This commit is contained in:
@@ -208,6 +208,7 @@ fn bool print_backtrace(String message, int backtraces_to_ignore, void *added_ba
|
||||
|
||||
fn void default_panic(String message, String file, String function, uint line) @if(env::NATIVE_STACKTRACE)
|
||||
{
|
||||
in_panic = true;
|
||||
$if $defined(io::stderr) && env::PANIC_MSG:
|
||||
if (!print_backtrace(message, 2))
|
||||
{
|
||||
@@ -224,7 +225,7 @@ macro void abort(String string = "Unrecoverable error reached", ...) @format(0)
|
||||
$$trap();
|
||||
}
|
||||
|
||||
bool in_panic @local = false;
|
||||
bool in_panic @private = false;
|
||||
|
||||
fn void default_panic(String message, String file, String function, uint line) @if (!env::NATIVE_STACKTRACE)
|
||||
{
|
||||
@@ -997,7 +998,7 @@ fn void sig_bus_error(CInt i, void* info, void* context)
|
||||
}
|
||||
$endif
|
||||
$endif
|
||||
$$trap();
|
||||
os::fastexit(128 + i);
|
||||
}
|
||||
|
||||
fn void sig_segmentation_fault(CInt i, void* p1, void* context)
|
||||
@@ -1012,15 +1013,39 @@ fn void sig_segmentation_fault(CInt i, void* p1, void* context)
|
||||
}
|
||||
$endif
|
||||
$endif
|
||||
$$trap();
|
||||
os::fastexit(128 + i);
|
||||
}
|
||||
|
||||
fn void sig_illegal_instruction(CInt i, void* p1, void* context)
|
||||
{
|
||||
if (in_panic) os::fastexit(128 + i);
|
||||
$if !env::NATIVE_STACKTRACE:
|
||||
sig_panic("Illegal instruction.");
|
||||
$else
|
||||
$if $defined(io::stderr):
|
||||
if (!print_backtrace("Illegal instruction.", 2, posix::stack_instruction(context)))
|
||||
{
|
||||
io::eprintn("\nERROR: Illegal instruction.");
|
||||
}
|
||||
$endif
|
||||
$endif
|
||||
os::fastexit(128 + i);
|
||||
}
|
||||
|
||||
char[64 * 1024] sig_stack @local @if(env::BACKTRACE && env::LINUX);
|
||||
|
||||
// Clean this up
|
||||
fn void install_signal_handlers() @init(101) @local @if(env::BACKTRACE)
|
||||
{
|
||||
$if env::LINUX:
|
||||
Stack_t ss = {
|
||||
.ss_sp = &sig_stack,
|
||||
.ss_size = sig_stack.len
|
||||
};
|
||||
libc::sigaltstack(&ss, null);
|
||||
$endif
|
||||
|
||||
posix::install_signal_handler(libc::SIGBUS, &sig_bus_error);
|
||||
posix::install_signal_handler(libc::SIGSEGV, &sig_segmentation_fault);
|
||||
posix::install_signal_handler(libc::SIGILL, &sig_illegal_instruction);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user