X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Finterrupt.c;h=467a2e4431cefab9fc412c8d5e12845f15fbdf6a;hb=7f0f521aa3f6b45259c5dfd5f7f11adcd1a7cac6;hp=4dc22af677a682e4475e24b24fbf5eca04c92402;hpb=358cad8bdef5c670e1bbe94c430bd27544995433;p=sbcl.git diff --git a/src/runtime/interrupt.c b/src/runtime/interrupt.c index 4dc22af..467a2e4 100644 --- a/src/runtime/interrupt.c +++ b/src/runtime/interrupt.c @@ -14,13 +14,9 @@ */ #include - +#include +#include #include -#ifdef mach /* KLUDGE: #ifdef on lowercase symbols? Ick. -- WHN 19990904 */ -#ifdef mips -#include -#endif -#endif #include "runtime.h" #include "arch.h" @@ -44,6 +40,7 @@ void sigaddset_blockable(sigset_t *s) sigaddset(s, SIGPIPE); sigaddset(s, SIGALRM); sigaddset(s, SIGURG); + sigaddset(s, SIGFPE); sigaddset(s, SIGTSTP); sigaddset(s, SIGCHLD); sigaddset(s, SIGIO); @@ -139,8 +136,8 @@ fake_foreign_function_call(os_context_t *context) == current_control_frame_pointer) { /* There is a small window during call where the callee's * frame isn't built yet. */ - if (LowtagOf(*os_context_register_addr(context, reg_CODE)) - == type_FunctionPointer) { + if (lowtag_of(*os_context_register_addr(context, reg_CODE)) + == FUN_POINTER_LOWTAG) { /* We have called, but not built the new frame, so * build it for them. */ current_control_frame_pointer[0] = @@ -213,6 +210,7 @@ undo_fake_foreign_function_call(os_context_t *context) * FREE_INTERRUPT_CONTEXT_INDEX? If so, we should say so. And * perhaps yes, unbind_to_here() really would be clearer and less * fragile.. */ + /* dan (2001.08.10) thinks the above supposition is probably correct */ unbind(); #ifdef reg_ALLOC @@ -319,7 +317,10 @@ interrupt_handle_pending(os_context_t *context) * anyway. Why we still need to copy the pending_mask into the * context given that we're now done with the context anyway, I * couldn't say. */ - memcpy(os_context_sigmask_addr(context), &pending_mask, sizeof(sigset_t)); +#if 0 + memcpy(os_context_sigmask_addr(context), &pending_mask, + 4 /* sizeof(sigset_t) */ ); +#endif sigemptyset(&pending_mask); if (pending_signal) { int signal = pending_signal; @@ -367,7 +368,7 @@ interrupt_handle_now(int signal, siginfo_t *info, void *void_context) if (ARE_SAME_HANDLER(handler.c, SIG_IGN)) { return; } - + #ifndef __i386__ were_in_lisp = !foreign_function_call_active; if (were_in_lisp) @@ -389,7 +390,7 @@ interrupt_handle_now(int signal, siginfo_t *info, void *void_context) * support decides to pass on it. */ lose("no handler for signal %d in interrupt_handle_now(..)", signal); - } else if (LowtagOf(handler.lisp) == type_FunctionPointer) { + } else if (lowtag_of(handler.lisp) == FUN_POINTER_LOWTAG) { /* Allocate the SAPs while the interrupts are still disabled. * (FIXME: Why? This is the way it was done in CMU CL, and it @@ -592,18 +593,19 @@ uninstall_low_level_interrupt_handlers_atexit(void) } } -/* Install a special low-level handler for signal; or if handler is - * SIG_DFL, remove any special handling for signal. +/* Undoably install a special low-level handler for signal; or if + * handler is SIG_DFL, remove any special handling for signal. * - * The "undoably_" part is because we also arrange with atexit() for - * the handler to be restored to its old value. This is for tidiness, - * though it shouldn't really matter in normal operation of the - * program, except perhaps that it removes a window when e.g. SIGINT - * would be handled bizarrely. The original motivation was that some - * memory corruption problems in OpenBSD ca sbcl-0.6.12.12 became - * unnecessarily hard to debug when they ended up back in gencgc.c - * code (courtesy of the gencgc SIGSEGV handler) after exit() was - * called. */ + * The "undoably" aspect is because we also arrange with atexit() for + * the handler to be restored to its old value. This is for tidiness: + * it shouldn't matter much ordinarily, but it does remove a window + * where e.g. memory fault signals (SIGSEGV or SIGBUS, which in + * ordinary operation of SBCL are sent to the generational garbage + * collector, then possibly onward to Lisp code) or SIGINT (which is + * ordinarily passed to Lisp code) could otherwise be handled + * bizarrely/brokenly because the Lisp code would try to deal with + * them using machinery (like stream output buffers) which has already + * been dismantled. */ void undoably_install_low_level_interrupt_handler (int signal, void handler(int, @@ -623,18 +625,19 @@ undoably_install_low_level_interrupt_handler (int signal, sigaddset_blockable(&sa.sa_mask); sa.sa_flags = SA_SIGINFO | SA_RESTART; - /* In the case of interrupt handlers which are modified - * more than once, we only save the original unmodified - * copy. */ + /* In the case of interrupt handlers which are modified more than + * once, we only save the original unmodified copy. */ if (!old_low_level_signal_handler_state->was_modified) { + struct sigaction *old_handler = + (struct sigaction*) &old_low_level_signal_handler_state->handler; old_low_level_signal_handler_state->was_modified = 1; - sigaction(signal, &sa, &old_low_level_signal_handler_state->handler); + sigaction(signal, &sa, old_handler); } else { sigaction(signal, &sa, NULL); } interrupt_low_level_handlers[signal] = - (ARE_SAME_HANDLER(handler,SIG_DFL) ? 0 : handler); + (ARE_SAME_HANDLER(handler, SIG_DFL) ? 0 : handler); } /* This is called from Lisp. */