/* Handler for SIGINT */ void sage_interrupt_handler(int sig) { #if ENABLE_DEBUG_INTERRUPT fprintf(stderr, "\n*** SIGINT *** %s sig_on\n", (_signals.sig_on_count > 0) ? "inside" : "outside"); print_backtrace(); #endif if (_signals.sig_on_count > 0) { if (_signals.block_sigint) { /* SIGINT is blocked, so simply set _signals.interrupt_received. */ _signals.interrupt_received = 1; return; } /* Raise KeyboardInterrupt */ PyErr_SetNone(PyExc_KeyboardInterrupt); /* Jump back to sig_on() (the first one if there is a stack) */ reset_CPU(); siglongjmp(_signals.env, sig); } else { /* Set an internal Python flag that an interrupt has been * raised. This will not immediately raise an exception, only * on the next call of PyErr_CheckSignals(). We cannot simply * raise an exception here because of Python's "global * interpreter lock" -- Jeroen Demeyer */ PyErr_SetInterrupt(); _signals.interrupt_received = 1; } }
/* Handler for SIGHUP, SIGINT */ void sage_interrupt_handler(int sig) { #if ENABLE_DEBUG_INTERRUPT if (sage_interrupt_debug_level >= 1) { fprintf(stderr, "\n*** SIG %i *** %s sig_on\n", sig, (_signals.sig_on_count > 0) ? "inside" : "outside"); if (sage_interrupt_debug_level >= 3) print_backtrace(); fflush(stderr); /* Store time of this signal, unless there is already a * pending signal. */ if (!_signals.interrupt_received) gettimeofday(&sigtime, NULL); } #endif if (_signals.sig_on_count > 0) { if (!_signals.block_sigint) { /* Actually raise an exception so Python can see it */ sig_raise_exception(sig); /* Jump back to sig_on() (the first one if there is a stack) */ reset_CPU(); siglongjmp(_signals.env, sig); } } else { /* Set the Python interrupt indicator, which will cause the * Python-level interrupt handler in sage/ext/c_lib.pyx to be * called. */ PyErr_SetInterrupt(); } /* If we are here, we cannot handle the interrupt immediately, so * we store the signal number for later use. But make sure we * don't overwrite a SIGHUP or SIGTERM which we already received. */ if (_signals.interrupt_received != SIGHUP && _signals.interrupt_received != SIGTERM) _signals.interrupt_received = sig; }
/* Handler for SIGILL, SIGABRT, SIGFPE, SIGBUS, SIGSEGV */ void sage_signal_handler(int sig) { sig_atomic_t inside = _signals.inside_signal_handler; _signals.inside_signal_handler = 1; if (inside == 0 && _signals.sig_on_count > 0) { /* We are inside sig_on(), so we can handle the signal! */ /* Message to be printed in the Python exception */ const char* msg = _signals.s; if (!msg) { /* Default: a message depending on which signal we got */ switch(sig) { case SIGILL: msg = "Illegal instruction"; break; case SIGABRT: msg = "Aborted"; break; case SIGFPE: msg = "Floating point exception"; break; case SIGBUS: msg = "Bus error"; break; case SIGSEGV: msg = "Segmentation fault"; break; default: msg = ""; } } /* Raise RuntimeError */ PyErr_SetString(PyExc_RuntimeError, msg); /* Jump back to sig_on() (the first one if there is a stack) */ reset_CPU(); siglongjmp(_signals.env, sig); } else { /* We are outside sig_on() and have no choice but to terminate Sage */ /* Reset all signals to their default behaviour and unblock * them in case something goes wrong as of now. */ signal(SIGILL, SIG_DFL); signal(SIGABRT, SIG_DFL); signal(SIGFPE, SIG_DFL); signal(SIGBUS, SIG_DFL); signal(SIGSEGV, SIG_DFL); sigprocmask(SIG_SETMASK, &sigmask_with_sigint, NULL); if (inside) sigdie(sig, "An error occured during signal handling."); /* Quit Sage with an appropriate message. */ switch(sig) { case SIGILL: sigdie(sig, "Unhandled SIGILL: An illegal instruction occurred in Sage."); break; /* This will not be reached */ case SIGABRT: sigdie(sig, "Unhandled SIGABRT: An abort() occurred in Sage."); break; /* This will not be reached */ case SIGFPE: sigdie(sig, "Unhandled SIGFPE: An unhandled floating point exception occurred in Sage."); break; /* This will not be reached */ case SIGBUS: sigdie(sig, "Unhandled SIGBUS: A bus error occurred in Sage."); break; /* This will not be reached */ case SIGSEGV: sigdie(sig, "Unhandled SIGSEGV: A segmentation fault occurred in Sage."); break; /* This will not be reached */ }; sigdie(sig, "Unknown signal received.\n"); } }
/* Handler for SIGILL, SIGABRT, SIGFPE, SIGBUS, SIGSEGV */ void sage_signal_handler(int sig) { sig_atomic_t inside = _signals.inside_signal_handler; _signals.inside_signal_handler = 1; if (inside == 0 && _signals.sig_on_count > 0) { /* We are inside sig_on(), so we can handle the signal! */ #if ENABLE_DEBUG_INTERRUPT if (sage_interrupt_debug_level >= 1) { fprintf(stderr, "\n*** SIG %i *** inside sig_on\n", sig); if (sage_interrupt_debug_level >= 3) print_backtrace(); fflush(stderr); gettimeofday(&sigtime, NULL); } #endif /* Actually raise an exception so Python can see it */ sig_raise_exception(sig); /* Jump back to sig_on() (the first one if there is a stack) */ reset_CPU(); siglongjmp(_signals.env, sig); } else { /* We are outside sig_on() and have no choice but to terminate Sage */ /* Reset all signals to their default behaviour and unblock * them in case something goes wrong as of now. */ signal(SIGHUP, SIG_DFL); signal(SIGINT, SIG_DFL); signal(SIGILL, SIG_DFL); signal(SIGABRT, SIG_DFL); signal(SIGFPE, SIG_DFL); signal(SIGBUS, SIG_DFL); signal(SIGSEGV, SIG_DFL); signal(SIGTERM, SIG_DFL); sigprocmask(SIG_SETMASK, &default_sigmask, NULL); if (inside) sigdie(sig, "An error occured during signal handling."); /* Quit Sage with an appropriate message. */ switch(sig) { case SIGILL: sigdie(sig, "Unhandled SIGILL: An illegal instruction occurred in Sage."); break; /* This will not be reached */ case SIGABRT: sigdie(sig, "Unhandled SIGABRT: An abort() occurred in Sage."); break; /* This will not be reached */ case SIGFPE: sigdie(sig, "Unhandled SIGFPE: An unhandled floating point exception occurred in Sage."); break; /* This will not be reached */ case SIGBUS: sigdie(sig, "Unhandled SIGBUS: A bus error occurred in Sage."); break; /* This will not be reached */ case SIGSEGV: sigdie(sig, "Unhandled SIGSEGV: A segmentation fault occurred in Sage."); break; /* This will not be reached */ }; sigdie(sig, "Unknown signal received.\n"); } }