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:
Manu Linares
2025-12-19 23:07:23 -03:00
committed by GitHub
parent 85166bc706
commit d2f59c5b3f
3 changed files with 103 additions and 29 deletions

View File

@@ -27,7 +27,7 @@ const CUInt SA_RESTART = env::LINUX ? 0x10000000 : 0x0002;
const CUInt SA_RESETHAND = env::LINUX ? 0x80000000 : 0x0004;
const CUInt SA_SIGINFO = env::LINUX ? 0x00000004 : 0x0040;
alias Sigset_t @if(!env::LINUX) = uint;
alias Sigset_t @if(env::DARWIN || env::BSD_FAMILY) = uint;
alias Sigset_t @if(env::LINUX) = ulong[16];
alias SigActionFunction = fn void(CInt, void*, void*);
@@ -38,10 +38,13 @@ struct Sigaction
SignalFunction sa_handler;
SigActionFunction sa_sigaction;
}
CInt sa_flags @if(env::BSD_FAMILY);
Sigset_t sa_mask; // 128
CInt sa_flags @if(!env::BSD_FAMILY);
void* sa_restorer @if(env::LINUX);
CInt sa_flags @if(env::DARWIN || env::BSD_FAMILY );
Sigset_t sa_mask @if(env::DARWIN || env::BSD_FAMILY);
Sigset_t sa_mask @if(env::LINUX);
CInt sa_flags @if(env::LINUX);
void* sa_restorer @if(env::LINUX);
}
struct Stack_t
@@ -62,6 +65,7 @@ struct Stack_t
extern fn CInt sigaltstack(Stack_t* ss, Stack_t* old_ss);
extern fn CInt sigaction(CInt signum, Sigaction *action, Sigaction *oldaction) @if(!env::NETBSD);
extern fn CInt sigaction(CInt signum, Sigaction *action, Sigaction *oldaction) @cname("__sigaction_siginfo") @if(env::NETBSD);
extern fn CInt sigemptyset(Sigset_t* set);
module libc::termios @if(env::LIBC &&& env::POSIX);