Example #1
0
/* 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;
    }
}
Example #2
0
/* 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;
}
Example #3
0
/* 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");
    }
}
Example #4
0
/* 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");
    }
}