From d5a6ad5bdb5bdea748a03e9bcc675e0dea33e1d5 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Thu, 13 Mar 2014 02:47:00 -0700 Subject: On platforms with sigaltstack, TXR programs can now catch the segmentation fault that occurs when running out of stack space, and escape by throwing an exception. Also, bugfix: save and restore the gc enable/disable state. Without this, if we are ever running cod in a gc disabled state and it jumps out, gc stays disabled. * configure: added check for sigaltstack. * gc.h (gc_enabled): Declaration added for existing variable. * signal.c (is_cpu_exception): New static function. (sig_handler): For cpu_exception type signals that pertain to the execution of some instruction, turn on async_sig_enabled, so that the signal is not deferred. Otherwise we will just return without calling the user-defined handler, restart the instruction and get into a loop. Also, disable gc around the handler just in case. One issue is that we might be on an alternate stack, which gc won't like. (setup_alt_stack, teardown_alt_stack): New static functions. (set_sig_handler): If we have sigaltstack, and are asked to set up a SEGV handler, then set it up on the alternate stack. * signal.h (extended_jmp_buf): Adding new member, gc. (extended_setjmp, extended_longjmp): use gc member to save and restore the gc_enable state across setjmp and longjmp. --- ChangeLog | 32 ++++++++++++++++++++++++++ configure | 22 ++++++++++++++++++ gc.h | 2 ++ signal.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ signal.h | 9 +++++++- 5 files changed, 141 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 5ec29e8d..3854494b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,35 @@ +2014-03-13 Kaz Kylheku + + On platforms with sigaltstack, TXR programs can now catch the + segmentation fault that occurs when running out of stack space, + and escape by throwing an exception. + + Also, bugfix: save and restore the gc enable/disable state. Without + this, if we are ever running cod in a gc disabled state and it jumps + out, gc stays disabled. + + * configure: added check for sigaltstack. + + * gc.h (gc_enabled): Declaration added for existing variable. + + * signal.c (is_cpu_exception): New static function. + (sig_handler): For cpu_exception type signals that pertain + to the execution of some instruction, turn on async_sig_enabled, + so that the signal is not deferred. Otherwise we will just + return without calling the user-defined handler, restart + the instruction and get into a loop. Also, disable gc around + the handler just in case. One issue is that we might be on + an alternate stack, which gc won't like. + (setup_alt_stack, teardown_alt_stack): New static functions. + (set_sig_handler): If we have sigaltstack, and are asked + to set up a SEGV handler, then set it up on the alternate + stack. + + * signal.h (extended_jmp_buf): Adding new member, gc. + (extended_setjmp, extended_longjmp): use gc member + to save and restore the gc_enable state across + setjmp and longjmp. + 2014-03-13 Kaz Kylheku * stream.c (open_process): If execvp fails, use errno as the diff --git a/configure b/configure index c897c7e2..ff7f67fa 100755 --- a/configure +++ b/configure @@ -1611,6 +1611,28 @@ else printf "no\n" fi +printf "Checking for sigaltstack ... " + +cat > conftest.c < +#include + +int main(void) +{ + stack_t ss; + ss.ss_sp = malloc(SIGSTKSZ); + ss.ss_size = SIGSTKSZ; + ss.ss_flags = 0; + return sigaltstack(&ss, 0); +} +! +if conftest ; then + printf "yes\n" + printf "#define HAVE_SIGALTSTACK 1\n" >> config.h +else + printf "no\n" +fi + printf "Checking for makedev ... " cat > conftest.c <