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. --- signal.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'signal.h') diff --git a/signal.h b/signal.h index 5aa49c82..f4968aca 100644 --- a/signal.h +++ b/signal.h @@ -62,6 +62,7 @@ typedef struct { sig_atomic_t se; sigset_t blocked; val de; + int gc; int rv; } extended_jmp_buf; @@ -69,10 +70,12 @@ typedef struct { (setjmp((EJB).jb) \ ? (async_sig_enabled = (EJB).se, \ dyn_env = (EJB).de, \ + gc_enabled = ((EJB).gc), \ sig_mask(SIG_SETMASK, &(EJB).blocked, 0), \ (EJB).rv) \ : ((EJB).se = async_sig_enabled, \ (EJB).de = dyn_env, \ + (EJB).gc = gc_enabled, \ (EJB).blocked = sig_blocked_cache, 0)) #define extended_longjmp(EJB, ARG) \ @@ -92,14 +95,18 @@ extern volatile sig_atomic_t async_sig_enabled; typedef struct { jmp_buf jb; val de; + int gc; int rv; } extended_jmp_buf; #define extended_setjmp(EJB) \ (setjmp((EJB).jb) \ ? (dyn_env = (EJB).de, \ + gc_enabled = ((EJB).gc), \ (EJB).rv) \ - : ((EJB).de = dyn_env, 0)) + : ((EJB).de = dyn_env, \ + (EJB).gc = gc_enabled, \ + 0)) #define extended_longjmp(EJB, ARG) \ ((EJB).rv = (ARG), longjmp((EJB).jb, 1)) -- cgit v1.2.3