1.0.1.1:
[sbcl.git] / src / runtime / x86-arch.c
index ba0cf36..c32aed7 100644 (file)
@@ -107,6 +107,8 @@ void arch_skip_instruction(os_context_t *context)
 
         case trap_PendingInterrupt:
         case trap_Halt:
+        case trap_SingleStepAround:
+        case trap_SingleStepBefore:
             /* only needed to skip the Code */
             break;
 
@@ -207,33 +209,39 @@ arch_do_displaced_inst(os_context_t *context, unsigned int orig_inst)
 }
 \f
 void
+restore_breakpoint_from_single_step(os_context_t * context)
+{
+    /* fprintf(stderr,"* single step trap %x\n", single_stepping); */
+#ifdef CANNOT_GET_TO_SINGLE_STEP_FLAG
+    /* Un-install single step helper instructions. */
+    *(single_stepping-3) = single_step_save1;
+    *(single_stepping-2) = single_step_save2;
+    *(single_stepping-1) = single_step_save3;
+#else
+    *context_eflags_addr(context) &= ~0x100;
+#endif
+    /* Re-install the breakpoint if possible. */
+    if (*os_context_pc_addr(context) == (int)single_stepping + 1) {
+        fprintf(stderr, "warning: couldn't reinstall breakpoint\n");
+    } else {
+        *((char *)single_stepping) = BREAKPOINT_INST;       /* x86 INT3 */
+        *((char *)single_stepping+1) = trap_Breakpoint;
+    }
+
+    single_stepping = NULL;
+    return;
+}
+
+void
 sigtrap_handler(int signal, siginfo_t *info, void *void_context)
 {
     os_context_t *context = (os_context_t*)void_context;
     unsigned int trap;
 
 #ifndef LISP_FEATURE_WIN32
-    if (single_stepping && (signal==SIGTRAP))
-    {
-        /* fprintf(stderr,"* single step trap %x\n", single_stepping); */
-
-#ifdef CANNOT_GET_TO_SINGLE_STEP_FLAG
-        /* Un-install single step helper instructions. */
-        *(single_stepping-3) = single_step_save1;
-        *(single_stepping-2) = single_step_save2;
-        *(single_stepping-1) = single_step_save3;
-#else
-        *context_eflags_addr(context) &= ~0x100;
-#endif
-        /* Re-install the breakpoint if possible. */
-        if (*os_context_pc_addr(context) == (int)single_stepping + 1) {
-            fprintf(stderr, "warning: couldn't reinstall breakpoint\n");
-        } else {
-            *((char *)single_stepping) = BREAKPOINT_INST;       /* x86 INT3 */
-            *((char *)single_stepping+1) = trap_Breakpoint;
-        }
-
-        single_stepping = NULL;
+    /* On Windows this is done in the SE handler. */
+    if (single_stepping && (signal==SIGTRAP)) {
+        restore_breakpoint_from_single_step(context);
         return;
     }
 #endif
@@ -304,6 +312,14 @@ sigtrap_handler(int signal, siginfo_t *info, void *void_context)
             (int)handle_fun_end_breakpoint(signal, info, context);
         break;
 
+    case trap_SingleStepAround:
+    case trap_SingleStepBefore:
+        arch_skip_instruction(context);
+        /* On x86 the fdefn / function is always in EAX, so we pass 0
+         * as the register_offset. */
+        handle_single_step_trap(context, trap, 0);
+        break;
+
     default:
         FSHOW((stderr,"/[C--trap default %d %d %x]\n",
                signal, trap, context));
@@ -312,14 +328,14 @@ sigtrap_handler(int signal, siginfo_t *info, void *void_context)
     }
 }
 
-static void
+void
 sigill_handler(int signal, siginfo_t *siginfo, void *void_context) {
     os_context_t *context = (os_context_t*)void_context;
 
     /* Triggering SIGTRAP using int3 is unreliable on OS X/x86, so
      * we need to use illegal instructions for traps.
      */
-#if defined(LISP_FEATURE_DARWIN)
+#if defined(LISP_FEATURE_DARWIN) && !defined(LISP_FEATURE_MACH_EXCEPTION_HANDLER)
     if (*((unsigned short *)*os_context_pc_addr(context)) == 0x0b0f) {
         *os_context_pc_addr(context) += 2;
         return sigtrap_handler(signal, siginfo, void_context);
@@ -345,7 +361,7 @@ arch_install_interrupt_handlers()
      * OS I haven't tested on?) and we have to go back to the old CMU
      * CL way, I hope there will at least be a comment to explain
      * why.. -- WHN 2001-06-07 */
-#ifndef LISP_FEATURE_WIN32
+#if !defined(LISP_FEATURE_WIN32) && !defined(LISP_FEATURE_MACH_EXCEPTION_HANDLER)
     undoably_install_low_level_interrupt_handler(SIGILL , sigill_handler);
     undoably_install_low_level_interrupt_handler(SIGTRAP, sigtrap_handler);
 #endif