void handle_breakpoint(os_context_t *context) { lispobj code; DX_ALLOC_SAP(context_sap, context); fake_foreign_function_call(context); #ifndef LISP_FEATURE_SB_SAFEPOINT unblock_gc_signals(0, 0); #endif code = find_code(context); #ifndef LISP_FEATURE_WIN32 /* Don't disallow recursive breakpoint traps. Otherwise, we can't * use debugger breakpoints anywhere in here. */ thread_sigmask(SIG_SETMASK, os_context_sigmask_addr(context), 0); #endif funcall3(StaticSymbolFunction(HANDLE_BREAKPOINT), compute_offset(context, code), code, context_sap); undo_fake_foreign_function_call(context); }
void sigill_handler(int signal, siginfo_t *siginfo, os_context_t *context) { /* Triggering SIGTRAP using int3 is unreliable on OS X/x86, so * we need to use illegal instructions for traps. */ #if defined(LISP_FEATURE_UD2_BREAKPOINTS) && !defined(LISP_FEATURE_MACH_EXCEPTION_HANDLER) if (*((unsigned short *)*os_context_pc_addr(context)) == UD2_INST) { *os_context_pc_addr(context) += 2; return sigtrap_handler(signal, siginfo, context); } #endif fake_foreign_function_call(context); lose("Unhandled SIGILL"); }
void handle_single_step_trap (os_context_t *context, int kind, int register_offset) { fake_foreign_function_call(context); #ifndef LISP_FEATURE_WIN32 thread_sigmask(SIG_SETMASK, os_context_sigmask_addr(context), 0); #endif funcall2(StaticSymbolFunction(HANDLE_SINGLE_STEP_TRAP), make_fixnum(kind), make_fixnum(register_offset)); undo_fake_foreign_function_call(context); /* blocks signals again */ }
void *handle_fun_end_breakpoint(os_context_t *context) { lispobj code, lra; struct code *codeptr; DX_ALLOC_SAP(context_sap, context); fake_foreign_function_call(context); #ifndef LISP_FEATURE_SB_SAFEPOINT unblock_gc_signals(0, 0); #endif code = find_code(context); codeptr = (struct code *)native_pointer(code); #ifndef LISP_FEATURE_WIN32 /* Don't disallow recursive breakpoint traps. Otherwise, we can't * use debugger breakpoints anywhere in here. */ thread_sigmask(SIG_SETMASK, os_context_sigmask_addr(context), 0); #endif funcall3(StaticSymbolFunction(HANDLE_BREAKPOINT), compute_offset(context, code), code, context_sap); lra = codeptr->constants[REAL_LRA_SLOT]; #ifdef LISP_FEATURE_PPC /* PPC now passes LRA objects in reg_LRA during return. Other * platforms should as well, but haven't been fixed yet. */ *os_context_register_addr(context, reg_LRA) = lra; #else #ifdef reg_CODE *os_context_register_addr(context, reg_CODE) = lra; #endif #endif undo_fake_foreign_function_call(context); #ifdef reg_LRA return (void *)(lra-OTHER_POINTER_LOWTAG+sizeof(lispobj)); #else return compute_pc(lra, fixnum_value(codeptr->constants[REAL_LRA_SLOT+1])); #endif }
void sigtrap_handler(HANDLER_ARGS) { unsigned int trap; os_context_t* os_context = (os_context_t *) context; #if 0 fprintf(stderr, "x86sigtrap: %8x %x\n", SC_PC(os_os_context), *(unsigned char *) (SC_PC(os_context) - 1)); fprintf(stderr, "sigtrap(%d %d %x)\n", signal, CODE(code), os_context); #endif if (single_stepping && (signal == SIGTRAP)) { #if 0 fprintf(stderr, "* Single step trap %p\n", single_stepping); #endif #ifdef SC_EFLAGS /* Disable single-stepping */ SC_EFLAGS(os_context) ^= 0x100; #else /* Un-install single step helper instructions. */ *(single_stepping - 3) = single_step_save1; *(single_stepping - 2) = single_step_save2; *(single_stepping - 1) = single_step_save3; DPRINTF(0, (stderr, "Uninstalling helper instructions\n")); #endif /* * Re-install the breakpoint if possible. */ if ((int) SC_PC(os_context) == (int) single_stepping + 1) fprintf(stderr, "* Breakpoint not re-install\n"); else { char *ptr = (char *) single_stepping; ptr[0] = BREAKPOINT_INST; /* x86 INT3 */ ptr[1] = trap_Breakpoint; } single_stepping = NULL; return; } /* This is just for info in case monitor wants to print an approx */ current_control_stack_pointer = (unsigned long *) SC_SP(os_context); RESTORE_FPU(os_context); /* * On entry %eip points just after the INT3 byte and aims at the * 'kind' value (eg trap_Cerror). For error-trap and Cerror-trap a * number of bytes will follow, the first is the length of the byte * arguments to follow. */ trap = *(unsigned char *) SC_PC(os_context); switch (trap) { case trap_PendingInterrupt: DPRINTF(0, (stderr, "<trap Pending Interrupt.>\n")); arch_skip_instruction(os_context); interrupt_handle_pending(os_context); break; case trap_Halt: { FPU_STATE(fpu_state); save_fpu_state(fpu_state); fake_foreign_function_call(os_context); lose("%%primitive halt called; the party is over.\n"); undo_fake_foreign_function_call(os_context); restore_fpu_state(fpu_state); arch_skip_instruction(os_context); break; } case trap_Error: case trap_Cerror: DPRINTF(0, (stderr, "<trap Error %x>\n", CODE(code))); interrupt_internal_error(signal, code, os_context, CODE(code) == trap_Cerror); break; case trap_Breakpoint: #if 0 fprintf(stderr, "*C break\n"); #endif SC_PC(os_context) -= 1; handle_breakpoint(signal, CODE(code), os_context); #if 0 fprintf(stderr, "*C break return\n"); #endif break; case trap_FunctionEndBreakpoint: SC_PC(os_context) -= 1; SC_PC(os_context) = (int) handle_function_end_breakpoint(signal, CODE(code), os_context); break; #ifdef trap_DynamicSpaceOverflowWarning case trap_DynamicSpaceOverflowWarning: interrupt_handle_space_overflow(SymbolFunction (DYNAMIC_SPACE_OVERFLOW_WARNING_HIT), os_context); break; #endif #ifdef trap_DynamicSpaceOverflowError case trap_DynamicSpaceOverflowError: interrupt_handle_space_overflow(SymbolFunction (DYNAMIC_SPACE_OVERFLOW_ERROR_HIT), os_context); break; #endif default: DPRINTF(0, (stderr, "[C--trap default %d %d %p]\n", signal, CODE(code), os_context)); interrupt_handle_now(signal, code, os_context); break; } }
void sigtrap_handler(HANDLER_ARGS) { unsigned int trap; #ifdef __linux__ GET_CONTEXT #endif #if 0 fprintf(stderr, "x86sigtrap: %8x %x\n", context->sc_pc, *(unsigned char *) (context->sc_pc - 1)); fprintf(stderr, "sigtrap(%d %d %x)\n", signal, code, context); #endif if (single_stepping && (signal == SIGTRAP)) { #if 0 fprintf(stderr, "* Single step trap %x\n", single_stepping); #endif #ifndef __linux__ /* 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 ^= 0x100; #endif /* * Re-install the breakpoint if possible. */ if ((int) context->sc_pc == (int) single_stepping + 1) fprintf(stderr, "* Breakpoint not re-install\n"); else { char *ptr = (char *) single_stepping; ptr[0] = BREAKPOINT_INST; /* x86 INT3 */ ptr[1] = trap_Breakpoint; } single_stepping = NULL; return; } /* This is just for info in case monitor wants to print an approx */ current_control_stack_pointer = (unsigned long *) context->sc_sp; #if defined(__linux__) && (defined(i386) || defined(__x86_64)) /* * Restore the FPU control word, setting the rounding mode to nearest. */ if (contextstruct.fpstate) #if defined(__x86_64) setfpucw(contextstruct.fpstate->cwd & ~0xc00); #else setfpucw(contextstruct.fpstate->cw & ~0xc00); #endif #endif /* * On entry %eip points just after the INT3 byte and aims at the * 'kind' value (eg trap_Cerror). For error-trap and Cerror-trap a * number of bytes will follow, the first is the length of the byte * arguments to follow. */ trap = *(unsigned char *) (context->sc_pc); switch (trap) { case trap_PendingInterrupt: DPRINTF(0, (stderr, "<trap Pending Interrupt.>\n")); arch_skip_instruction(context); interrupt_handle_pending(context); break; case trap_Halt: { #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) int fpu_state[27]; fpu_save(fpu_state); #endif fake_foreign_function_call(context); lose("%%primitive halt called; the party is over.\n"); undo_fake_foreign_function_call(context); #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) fpu_restore(fpu_state); #endif arch_skip_instruction(context); break; } case trap_Error: case trap_Cerror: DPRINTF(0, (stderr, "<trap Error %d>\n", code)); #ifdef __linux__ interrupt_internal_error(signal, contextstruct, code == trap_Cerror); #else interrupt_internal_error(signal, code, context, code == trap_Cerror); #endif break; case trap_Breakpoint: #if 0 fprintf(stderr, "*C break\n"); #endif (char *) context->sc_pc -= 1; handle_breakpoint(signal, code, context); #if 0 fprintf(stderr, "*C break return\n"); #endif break; case trap_FunctionEndBreakpoint: (char *) context->sc_pc -= 1; context->sc_pc = (int) handle_function_end_breakpoint(signal, code, context); break; #ifdef DYNAMIC_SPACE_OVERFLOW_WARNING_HIT case trap_DynamicSpaceOverflowWarning: interrupt_handle_space_overflow(SymbolFunction (DYNAMIC_SPACE_OVERFLOW_WARNING_HIT), context); break; #endif #ifdef DYNAMIC_SPACE_OVERFLOW_ERROR_HIT case trap_DynamicSpaceOverflowError: interrupt_handle_space_overflow(SymbolFunction (DYNAMIC_SPACE_OVERFLOW_ERROR_HIT), context); break; #endif default: DPRINTF(0, (stderr, "[C--trap default %d %d %x]\n", signal, code, context)); #ifdef __linux__ interrupt_handle_now(signal, contextstruct); #else interrupt_handle_now(signal, code, context); #endif break; } }