From 1884e0bc0174ea4e98ded1db8e1fdf56d741baf0 Mon Sep 17 00:00:00 2001 From: Ayrton Munoz Date: Mon, 11 Aug 2025 12:18:22 -0700 Subject: [PATCH] misc/test_runner: Replace _exit with syscall after segfault libia2.a provides exit, _exit and call_libc_exit but we can't call any of these after catching a segfault because we're in a signal handler at that point. exit accesses ia2_stackptr_0 (a thread-local) using the %fs segment register whihc does not work from a signal handler. _exit just jumps to exit so it also doesn't work for the same reason and call_libc_exit calls dlopen which calls many functions that are not async-signal-safe. This commit replaces the call to _exit in the signal handler for tests with a syscall for exit instead. --- misc/test_runner/test_runner.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/misc/test_runner/test_runner.c b/misc/test_runner/test_runner.c index e1ed85558..123430d00 100644 --- a/misc/test_runner/test_runner.c +++ b/misc/test_runner/test_runner.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -68,11 +69,19 @@ void print_mpk_message(int sig) { } /* Write directly to stdout since printf is not async-signal-safe */ write(1, msg, strlen(msg)); + /* + * None of the various wrappers libia2.a defines for exit are + * async-signal-safe because they access thread-locals via the %fs segment + * register or call dlopen and other functions that are not + * async-signal-safe. Instead we just use a syscall since we just care about + * terminating the process without trying to do any other clean up at this + * point + */ if (!expect_fault) { - _exit(-1); + syscall(SYS_exit, -1); } } - _exit(0); + syscall(SYS_exit, 0); } int main() {