diff options
| author | Mattias Andrée <m@maandree.se> | 2026-05-10 13:37:34 +0200 |
|---|---|---|
| committer | Mattias Andrée <m@maandree.se> | 2026-05-10 13:37:34 +0200 |
| commit | b7e8928005079171c7595fd336a76f655daed48a (patch) | |
| tree | 9fa87ba8ada6cc52e343c32789ff7225d817e4fa /libtest/libtest_stack_on_signal.c | |
| parent | Misc (diff) | |
| download | librecrypt-b7e8928005079171c7595fd336a76f655daed48a.tar.gz librecrypt-b7e8928005079171c7595fd336a76f655daed48a.tar.bz2 librecrypt-b7e8928005079171c7595fd336a76f655daed48a.tar.xz | |
Improvements to libtest
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to 'libtest/libtest_stack_on_signal.c')
| -rw-r--r-- | libtest/libtest_stack_on_signal.c | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/libtest/libtest_stack_on_signal.c b/libtest/libtest_stack_on_signal.c new file mode 100644 index 0000000..0f92972 --- /dev/null +++ b/libtest/libtest_stack_on_signal.c @@ -0,0 +1,102 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" +#ifndef TEST + +# ifdef WITH_BACKTRACE + + +static void +stack_dumper(int sig, siginfo_t *info, void *ucontext) +{ + (void) sig; + (void) info; + libtest_print_backtrace(stderr, "crashed at ", " by ", 0u, NULL, ucontext); +} + + +static stack_t ss; +static size_t have_ss = 0u; + + +static void +create_altstack(void) +{ + if (have_ss++) + return; + ss.ss_sp = libtest_real_mmap(NULL, (size_t)SIGSTKSZ, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + assert(ss.ss_sp != MAP_FAILED); + ss.ss_size = (size_t)SIGSTKSZ; + ss.ss_flags = 0; + assert(!sigaltstack(&ss, NULL)); +} + + +static void +destroy_altstack(void) +{ + if (--have_ss) + return; + assert(!libtest_real_munmap(ss.ss_sp, ss.ss_size)); +} + + +void +libtest_stack_on_signal(int signo, struct sigaction *old_out) +{ + struct sigaction sa; + + create_altstack(); + + memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = &stack_dumper; + sa.sa_flags = (int)(SA_RESETHAND | SA_SIGINFO); + if (have_ss) + sa.sa_flags |= SA_ONSTACK; + sigfillset(&sa.sa_mask); + + assert(!sigaction(signo, &sa, old_out)); +} + + +void +libtest_stop_stack_on_signal(int signo, const struct sigaction *old) +{ + assert(!sigaction(signo, old, NULL)); + destroy_altstack(); +} + + +#else + + +void +libtest_stack_on_signal(int signo, struct sigaction *old_out) +{ + (void) signo; + (void) old_out; +} + +void +libtest_stop_stack_on_signal(int signo, const struct sigaction *old) +{ + (void) signo; + (void) old; +} + + +# endif + + +#else + + +CONST int +main(void) +{ + /* How would one even test this, and what would be the point? */ + return 0; +} + + +#endif |
