Date: Wednesday, August 31, 2011 @ 21:39:56 Author: rtoy Path: /project/cmucl/cvsroot/src
Modified: general-info/release-20c.txt lisp/Darwin-os.c
Make the stack checking feature actually work on Darwin. Previously, stack overflows would crash lisp.
Darwin-os.c: o Need to check for stack overflow in the sigbus handler. (Without that, it's treated as a regular bus error.) o Add the rest of the infrastructure to handle the stack overflow.
release-20c.txt: o Update
------------------------------+ general-info/release-20c.txt | 3 +++ lisp/Darwin-os.c | 41 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 2 deletions(-)
Index: src/general-info/release-20c.txt diff -u src/general-info/release-20c.txt:1.30 src/general-info/release-20c.txt:1.31 --- src/general-info/release-20c.txt:1.30 Mon Aug 22 21:16:04 2011 +++ src/general-info/release-20c.txt Wed Aug 31 21:39:55 2011 @@ -138,6 +138,9 @@ signals an error in DGETTEXT trying to translate the null documentation string. - Reduce unnecessary consing of SAPs in ROOM. + - Make stack overflow checking actually work on Mac OS X. The + implementation had the :stack-checking feature, but it didn't + actually prevent stack overflows from crashing lisp.
* Trac Tickets: Index: src/lisp/Darwin-os.c diff -u src/lisp/Darwin-os.c:1.31 src/lisp/Darwin-os.c:1.32 --- src/lisp/Darwin-os.c:1.31 Sun Dec 26 08:04:43 2010 +++ src/lisp/Darwin-os.c Wed Aug 31 21:39:56 2011 @@ -14,7 +14,7 @@ * Frobbed for OpenBSD by Pierre R. Mai, 2001. * Frobbed for Darwin by Pierre R. Mai, 2003. * - * $Header: /project/cmucl/cvsroot/src/lisp/Darwin-os.c,v 1.31 2010/12/26 16:04:43 rswindells Exp $ + * $Header: /project/cmucl/cvsroot/src/lisp/Darwin-os.c,v 1.32 2011/09/01 04:39:56 rtoy Exp $ * */
@@ -453,6 +453,23 @@ return FALSE; } +static void +sigbus_handle_now(HANDLER_ARGS) +{ + interrupt_handle_now(signal, code, context); +} + + +static int tramp_signal; +static siginfo_t tramp_code; +static ucontext_t tramp_context; + +static void +sigbus_handler_tramp(void) +{ + sigbus_handle_now(tramp_signal, &tramp_code, &tramp_context); +} +
static void sigbus_handler(HANDLER_ARGS) @@ -461,6 +478,11 @@ caddr_t fault_addr = code->si_addr; #endif
+#ifdef RED_ZONE_HIT + if (os_control_stack_overflow((void *) fault_addr, context)) + return; +#endif + #ifdef __ppc__ DPRINTF(0, (stderr, "sigbus:\n")); DPRINTF(0, (stderr, " PC = %p\n", SC_PC(context))); @@ -472,6 +494,21 @@ DPRINTF(0, (stderr, " foreign_function_call = %d\n", foreign_function_call_active)); #endif
+#ifdef RED_ZONE_HIT + { + /* + * Switch back to the normal stack and invoke the Lisp signal + * handler there. Global variables are used to pass the + * context * to the other stack. + */ + tramp_signal = signal; + tramp_code = *code; + tramp_context = *context; + SC_PC(context) = sigbus_handler_tramp; + return; + } +#endif + #if defined(GENCGC) #if defined(SIGSEGV_VERBOSE) fprintf(stderr, "Signal %d, fault_addr=%x, page_index=%d:\n", @@ -485,7 +522,7 @@ #endif /* a *real* protection fault */ fprintf(stderr, "sigbus_handler: Real protection violation: %p\n", fault_addr); - interrupt_handle_now(signal, code, context); + sigbus_handle_now(signal, code, context); #ifdef __ppc__ /* Work around G5 bug; fix courtesy gbyers via chandler */ sigreturn(context);