0.9.10.30:
authorCyrus Harmon <ch-sbcl@bobobeach.com>
Wed, 15 Mar 2006 03:01:46 +0000 (03:01 +0000)
committerCyrus Harmon <ch-sbcl@bobobeach.com>
Wed, 15 Mar 2006 03:01:46 +0000 (03:01 +0000)
    Fix Darwin instability problems. Darwin isn't reliably firing
    SIGTRAP handlers, so use UD2 to generate a SIGILL instead of INT3
    to generate a SIGTRAP and we check for this in the SIGILL handler
    and DTRT if we see this by calling the sigtrap_handler
    ... Define TRAP that uses UD2 (0x0b0f or 0F 0B) instead on Darwin
        and INT3 elsewhere in x86-assem.S
    ... Removed the bogus sigaltstack (was Darwin only, now gone) in
        bsd-os.c that I added in the course of trying to fix this
        problem
    ... #+darwin use UD2 instead of INT3 in compiler/x86 and add
        support for disassembling this as break

src/compiler/x86/insts.lisp
src/compiler/x86/macros.lisp
src/runtime/bsd-os.c
src/runtime/x86-arch.c
src/runtime/x86-assem.S

index 9eed6f8..f58b42a 100644 (file)
                                      :default-printer '(:name :tab code))
  (op :field (byte 8 0))
  (code :field (byte 8 8)))
+
+;;; Two byte instruction with an immediate byte argument.
+;;;
+(sb!disassem:define-instruction-format (word-imm 24
+                                                 :default-printer '(:name :tab code))
+    (op :field (byte 16 0))
+  (code :field (byte 8 16)))
+
 \f
 ;;;; primitive emitters
 
 
 (define-instruction break (segment code)
   (:declare (type (unsigned-byte 8) code))
-  (:printer byte-imm ((op #b11001100)) '(:name :tab code)
-            :control #'break-control)
-  (:emitter
-   (emit-byte segment #b11001100)
+  #-darwin (:printer byte-imm ((op #b11001100)) '(:name :tab code)
+                     :control #'break-control)
+  #+darwin (:printer word-imm ((op #b0000101100001111)) '(:name :tab code)
+                     :control #'break-control)
+  (:emitter
+   #-darwin (emit-byte segment #b11001100)
+   ;; On darwin, trap handling via SIGTRAP is unreliable, therefore we
+   ;; throw a sigill with 0x0b0f instead and check for this in the
+   ;; SIGILL handler and pass it on to the sigtrap handler if
+   ;; appropriate
+   #+darwin (emit-word segment #b0000101100001111)
    (emit-byte segment code)))
 
 (define-instruction int (segment number)
index 73254c0..8a1dc87 100644 (file)
 (eval-when (#-sb-xc :compile-toplevel :load-toplevel :execute)
   (defun emit-error-break (vop kind code values)
     (let ((vector (gensym)))
-      `((inst int 3)                            ; i386 breakpoint instruction
+      `((progn
+          #-darwin (inst int 3)         ; i386 breakpoint instruction
+          ;; CLH 20060314
+          ;; On Darwin, we need to use #x0b0f instead of int3 in order
+          ;; to generate a SIGILL instead of a SIGTRAP as darwin/x86
+          ;; doesn't seem to be reliably firing SIGTRAP
+          ;; handlers. Hopefully this will be fixed by Apple at a
+          ;; later date.
+          #+darwin (inst word #x0b0f))
         ;; The return PC points here; note the location for the debugger.
         (let ((vop ,vop))
           (when vop
index 6372c42..f9cf70c 100644 (file)
@@ -58,10 +58,6 @@ static void netbsd_init();
 static void freebsd_init();
 #endif /* __FreeBSD__ */
 
-#if defined(LISP_FEATURE_DARWIN) && defined(LISP_FEATURE_X86)
-static void x86_darwin_init();
-#endif
-
 void
 os_init(char *argv[], char *envp[])
 {
@@ -73,9 +69,6 @@ os_init(char *argv[], char *envp[])
 #ifdef __FreeBSD__
     freebsd_init();
 #endif /* __FreeBSD__ */
-#if defined(LISP_FEATURE_DARWIN) && defined(LISP_FEATURE_X86)
-    x86_darwin_init();
-#endif
 }
 
 int *os_context_pc_addr(os_context_t *context)
@@ -353,19 +346,6 @@ int arch_os_thread_cleanup(struct thread *thread) {
 }
 #endif
 
-#if defined(LISP_FEATURE_DARWIN) && defined(LISP_FEATURE_X86)
-static void x86_darwin_init()
-{
-    struct sigaltstack sigstack;
-    sigstack.ss_sp = os_allocate(32*SIGSTKSZ);
-    if (sigstack.ss_sp) {
-        sigstack.ss_flags=0;
-        sigstack.ss_size = 32*SIGSTKSZ;
-        sigaltstack(&sigstack,0);
-    }
-}
-#endif
-
 #ifdef LISP_FEATURE_DARWIN
 /* defined in ppc-darwin-os.c instead */
 #elif defined(LISP_FEATURE_FREEBSD)
index 5b98eb3..9d76b93 100644 (file)
@@ -304,6 +304,14 @@ sigtrap_handler(int signal, siginfo_t *info, void *void_context)
 static void
 sigill_handler(int signal, siginfo_t *siginfo, void *void_context) {
     os_context_t *context = (os_context_t*)void_context;
+
+#if defined(LISP_FEATURE_DARWIN)
+    if (*((unsigned short *)*os_context_pc_addr(context)) == 0x0b0f) {
+        *os_context_pc_addr(context) += 2;
+        return sigtrap_handler(signal, siginfo, void_context);
+    }
+#endif
+
     fake_foreign_function_call(context);
     monitor_or_something();
 }
index 33820b4..0deae4f 100644 (file)
 #define SIZE(name)
 #endif
 
+/*
+ * x86/darwin (as of MacOS X 10.4.5) doesn't reliably file signal
+ * handlers (SIGTRAP or Mach exception handlers) for 0xCC, wo we have
+ * to use ud2 instead. ud2 is an undefined opcode, #x0b0f, or
+ * 0F 0B in low-endian notation, that causes SIGILL to fire. We check
+ * for this instruction in the SIGILL handler and if we see it, we
+ * advance the EIP by two bytes to skip over ud2 instruction and
+ * call sigtrap_handler. */
 #if defined(LISP_FEATURE_DARWIN)
 #define END()
+#define TRAP ud2
 #else
 #define END() .end
+#define TRAP int3
 #endif
 
        .text
@@ -336,7 +346,7 @@ GNAME(fpu_restore):
        TYPE(GNAME(undefined_tramp))
         .byte   0, 0, 0, SIMPLE_FUN_HEADER_WIDETAG
 GNAME(undefined_tramp):
-       int3
+       TRAP
        .byte   trap_Error
         .byte   2
         .byte   UNDEFINED_FUN_ERROR
@@ -385,7 +395,7 @@ multiple_value_return:
        
        .globl GNAME(fun_end_breakpoint_trap)
 GNAME(fun_end_breakpoint_trap):
-       int3
+       TRAP
        .byte   trap_FunEndBreakpoint
        hlt                     # We should never return here.
 
@@ -397,7 +407,7 @@ GNAME(fun_end_breakpoint_end):
        TYPE(GNAME(do_pending_interrupt))
        .align  align_4byte,0x90
 GNAME(do_pending_interrupt):
-       int3
+       TRAP
        .byte   trap_PendingInterrupt
        ret
        SIZE(GNAME(do_pending_interrupt))
@@ -861,7 +871,7 @@ GNAME(sigtrap_trampoline):
        call    GNAME(sigtrap_wrapper)
        pop     %eax
        pop     %eax
-       int3
+       TRAP
        .byte   trap_ContextRestore
        hlt                     # We should never return here.
         
@@ -877,7 +887,7 @@ GNAME(exception_trampoline):
        call    GNAME(handle_win32_exception_wrapper)
        pop     %eax
        pop     %eax
-       int3
+       TRAP
        .byte   trap_ContextRestore
        hlt                     # We should never return here.
 #endif