From: Christophe Rhodes Date: Mon, 14 Mar 2005 09:54:43 +0000 (+0000) Subject: 0.8.20.20: X-Git-Url: http://repo.macrolet.net/gitweb/?a=commitdiff_plain;h=1f23c9f7828d8aebeda92c8c1126114e10461ffa;p=sbcl.git 0.8.20.20: Fix handling of SIG_MEMORY_FAULT in the (conceptual) interrupt_handle_now() case -- arrange_return_to_lisp_function() to MEMORY_FAULT_ERROR instead, for x86(-64). (I hope I haven't broken anything on other architectures... please check!) ... also log problem with reporting the error in BUGS --- diff --git a/BUGS b/BUGS index e6de843..93b3ecb 100644 --- a/BUGS +++ b/BUGS @@ -2083,3 +2083,17 @@ WORKAROUND: Type deriver for CONJUGATE thinks that it returns an object of the same type as its argument, which is wrong for such types as (EQL #C(1 2)). + +377: Memory fault error reporting + On those architectures where :C-STACK-IS-CONTROL-STACK is in + *FEATURES*, we handle SIG_MEMORY_FAULT (SEGV or BUS) on an altstack, + so we cannot handle the signal directly (as in interrupt_handle_now()) + in the case when the signal comes from some external agent (the user + using kill(1), or a fault in some foreign code, for instance). As + of sbcl-0.8.20.20, this is fixed by calling + arrange_return_to_lisp_function() to a new error-signalling + function, but as a result the error reporting is poor: we cannot + even tell the user at which address the fault occurred. We should + arrange such that arguments can be passed to the function called from + arrange_return_to_lisp_function(), but this looked hard to do in + general without suffering from memory leaks. diff --git a/NEWS b/NEWS index 4caf632..e91d294 100644 --- a/NEWS +++ b/NEWS @@ -20,6 +20,12 @@ changes in sbcl-0.8.21 (0.9alpha.1?) relative to sbcl-0.8.20: are now more amenable to inspection by INSPECT. * workaround for bug 354: XEPs no longer appear in backtraces unless explicitly requested. + * fixed bug: receiving the signal which results from attempting to + write to mprotect()ed memory (SIGSEGV on Linux and some *BSDs, + SIGBUS on other *BSDs) on architectures where the C stack is also + the Lisp stack (x86 and x86-64) from foreign code no longer leads + to debugger confusion or wild instability. (reported by Cheuksan + Wang) * fixed bug: COUNT and EQUAL no longer issue compiler efficiency notes when operating on objects known to be SIMPLE-BIT-VECTORs. (reported by Lutz Euler) diff --git a/src/code/error.lisp b/src/code/error.lisp index aae384b..9d8082b 100644 --- a/src/code/error.lisp +++ b/src/code/error.lisp @@ -121,3 +121,9 @@ (format stream "Control stack exhausted (no more space for function call frames). This is probably due to heavily nested or infinitely recursive function calls, or a tail call that SBCL cannot or has not optimized away.")))) +(define-condition memory-fault-error (error) + () + (:report + (lambda (condition stream) + (declare (ignore condition)) + (format stream "memory fault")))) \ No newline at end of file diff --git a/src/code/interr.lisp b/src/code/interr.lisp index b3ea6a1..b230d79 100644 --- a/src/code/interr.lisp +++ b/src/code/interr.lisp @@ -461,3 +461,6 @@ (defun undefined-alien-function-error () (error 'undefined-alien-function-error)) + +(defun memory-fault-error () + (error 'memory-fault-error)) \ No newline at end of file diff --git a/src/compiler/generic/genesis.lisp b/src/compiler/generic/genesis.lisp index 98c35ff..6c1ae19 100644 --- a/src/compiler/generic/genesis.lisp +++ b/src/compiler/generic/genesis.lisp @@ -1251,6 +1251,7 @@ core and return a descriptor to it." (frob sb!kernel::control-stack-exhausted-error) (frob sb!kernel::undefined-alien-variable-error) (frob sb!kernel::undefined-alien-function-error) + (frob sb!kernel::memory-fault-error) (frob sb!di::handle-breakpoint) (frob sb!di::handle-fun-end-breakpoint) (frob sb!thread::handle-thread-exit)) diff --git a/src/compiler/x86-64/parms.lisp b/src/compiler/x86-64/parms.lisp index 15276a0..de4af8a 100644 --- a/src/compiler/x86-64/parms.lisp +++ b/src/compiler/x86-64/parms.lisp @@ -177,6 +177,7 @@ sb!kernel::control-stack-exhausted-error sb!kernel::undefined-alien-variable-error sb!kernel::undefined-alien-function-error + sb!kernel::memory-fault-error sb!di::handle-breakpoint fdefinition-object #!+sb-thread sb!thread::handle-thread-exit diff --git a/src/compiler/x86/parms.lisp b/src/compiler/x86/parms.lisp index f12d293..a380896 100644 --- a/src/compiler/x86/parms.lisp +++ b/src/compiler/x86/parms.lisp @@ -271,6 +271,7 @@ sb!kernel::control-stack-exhausted-error sb!kernel::undefined-alien-variable-error sb!kernel::undefined-alien-function-error + sb!kernel::memory-fault-error sb!di::handle-breakpoint fdefinition-object #!+sb-thread sb!thread::handle-thread-exit diff --git a/src/runtime/bsd-os.c b/src/runtime/bsd-os.c index 63b28ef..5d09d9d 100644 --- a/src/runtime/bsd-os.c +++ b/src/runtime/bsd-os.c @@ -188,9 +188,11 @@ memory_fault_handler(int signal, siginfo_t *siginfo, void *void_context) os_context_t *context = arch_os_get_context(&void_context); if (!gencgc_handle_wp_violation(fault_addr)) if(!handle_guard_page_triggered(context,fault_addr)) - /* FIXME is this context or void_context? not that it */ - /* makes a difference currently except on linux/sparc */ - interrupt_handle_now(signal, siginfo, void_context); +#ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK + arrange_return_to_lisp_function(context, SymbolFunction(MEMORY_FAULT_HANDLER)); +#else + interrupt_handle_now(signal, siginfo, context); +#endif } void os_install_interrupt_handlers(void) diff --git a/src/runtime/interrupt.h b/src/runtime/interrupt.h index ba0a6bd..642160e 100644 --- a/src/runtime/interrupt.h +++ b/src/runtime/interrupt.h @@ -44,6 +44,7 @@ struct interrupt_data { extern void interrupt_init(); extern void fake_foreign_function_call(os_context_t* context); extern void undo_fake_foreign_function_call(os_context_t* context); +extern void arrange_return_to_lisp_function(os_context_t *, lispobj); extern void interrupt_handle_now(int, siginfo_t*, void*); extern void interrupt_handle_pending(os_context_t*); extern void interrupt_internal_error(int, siginfo_t*, os_context_t*, diff --git a/src/runtime/linux-os.c b/src/runtime/linux-os.c index a30ab80..26304a8 100644 --- a/src/runtime/linux-os.c +++ b/src/runtime/linux-os.c @@ -28,10 +28,12 @@ #include "os.h" #include "arch.h" #include "globals.h" -#include "sbcl.h" #include "interrupt.h" #include "interr.h" #include "lispregs.h" +#include "runtime.h" +#include "genesis/static-symbols.h" +#include "genesis/fdefn.h" #include #include @@ -225,7 +227,11 @@ sigsegv_handler(int signal, siginfo_t *info, void* void_context) void* fault_addr = (void*)info->si_addr; if (!gencgc_handle_wp_violation(fault_addr)) if(!handle_guard_page_triggered(context,fault_addr)) - interrupt_handle_now(signal, info, void_context); +#ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK + arrange_return_to_lisp_function(context, SymbolFunction(MEMORY_FAULT_ERROR)); +#else + interrupt_handle_now(signal, info, context); +#endif } #else diff --git a/version.lisp-expr b/version.lisp-expr index 394b37b..27d35ea 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -17,4 +17,4 @@ ;;; checkins which aren't released. (And occasionally for internal ;;; versions, especially for internal versions off the main CVS ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"0.8.20.19" +"0.8.20.20"