0.8.20.20:
authorChristophe Rhodes <csr21@cam.ac.uk>
Mon, 14 Mar 2005 09:54:43 +0000 (09:54 +0000)
committerChristophe Rhodes <csr21@cam.ac.uk>
Mon, 14 Mar 2005 09:54:43 +0000 (09:54 +0000)
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

BUGS
NEWS
src/code/error.lisp
src/code/interr.lisp
src/compiler/generic/genesis.lisp
src/compiler/x86-64/parms.lisp
src/compiler/x86/parms.lisp
src/runtime/bsd-os.c
src/runtime/interrupt.h
src/runtime/linux-os.c
version.lisp-expr

diff --git a/BUGS b/BUGS
index e6de843..93b3ecb 100644 (file)
--- 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 (file)
--- 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)
index aae384b..9d8082b 100644 (file)
       (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
index b3ea6a1..b230d79 100644 (file)
 
 (defun undefined-alien-function-error ()
   (error 'undefined-alien-function-error))
+
+(defun memory-fault-error ()
+  (error 'memory-fault-error))
\ No newline at end of file
index 98c35ff..6c1ae19 100644 (file)
@@ -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))
index 15276a0..de4af8a 100644 (file)
     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
index f12d293..a380896 100644 (file)
     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
index 63b28ef..5d09d9d 100644 (file)
@@ -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)
index ba0a6bd..642160e 100644 (file)
@@ -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*,
index a30ab80..26304a8 100644 (file)
 #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 <sys/socket.h>
 #include <sys/utsname.h>
 
@@ -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
index 394b37b..27d35ea 100644 (file)
@@ -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"