Ticket #14029: 14029_SIGQUIT.patch

File 14029_SIGQUIT.patch, 10.5 KB (added by jdemeyer, 8 years ago)
  • c_lib/include/interrupt.h

    # HG changeset patch
    # User Jeroen Demeyer <jdemeyer@cage.ugent.be>
    # Date 1359390812 -3600
    # Node ID 4cec9d4aa99efd6efa12f5273ec883f0efd85913
    # Parent  247260f2363e6a29ea2e424e775efb99c2a3ec03
    Handle SIGQUIT also
    
    diff --git a/c_lib/include/interrupt.h b/c_lib/include/interrupt.h
    a b  
    1313SystemExit, causing Python to exit.  The latter signals also redirect
    1414stdin from /dev/null, to cause interactive sessions to exit also.
    1515
    16 (2) critical signals: SIGILL, SIGABRT, SIGFPE, SIGBUS, SIGSEGV.
     16(2) critical signals: SIGQUIT, SIGILL, SIGABRT, SIGFPE, SIGBUS, SIGSEGV.
    1717These are critical because they cannot be ignored.  If they happen
    1818outside of sig_on(), we can only exit Sage with the dreaded
    1919"unhandled SIG..." message.  Inside of sig_on(), they can be handled
    20 and raise a RuntimeError.
     20and raise a RuntimeError.  SIGQUIT will never be handled and always
     21causes Sage to exit.
    2122
    2223
    2324AUTHORS:
     
    2829
    2930- Jeroen Demeyer (2013-01-11): handle SIGHUP also (#13908)
    3031
     32- Jeroen Demeyer (2013-01-28): handle SIGQUIT also (#14029)
     33
    3134*/
    3235
    3336/*****************************************************************************
  • c_lib/src/interrupt.c

    diff --git a/c_lib/src/interrupt.c b/c_lib/src/interrupt.c
    a b  
    99
    1010- Jeroen Demeyer (2013-01-11): handle SIGHUP also (#13908)
    1111
     12- Jeroen Demeyer (2013-01-28): handle SIGQUIT also (#14029)
     13
    1214*/
    1315
    1416/*****************************************************************************
     
    135137        _signals.interrupt_received = sig;
    136138}
    137139
    138 /* Handler for SIGILL, SIGABRT, SIGFPE, SIGBUS, SIGSEGV */
     140/* Handler for SIGQUIT, SIGILL, SIGABRT, SIGFPE, SIGBUS, SIGSEGV */
    139141void sage_signal_handler(int sig)
    140142{
    141143    sig_atomic_t inside = _signals.inside_signal_handler;
    142144    _signals.inside_signal_handler = 1;
    143145
    144     if (inside == 0 && _signals.sig_on_count > 0)
     146    if (inside == 0 && _signals.sig_on_count > 0 && sig != SIGQUIT)
    145147    {
    146148        /* We are inside sig_on(), so we can handle the signal! */
    147149#if ENABLE_DEBUG_INTERRUPT
     
    168170         * them in case something goes wrong as of now. */
    169171        signal(SIGHUP, SIG_DFL);
    170172        signal(SIGINT, SIG_DFL);
     173        signal(SIGQUIT, SIG_DFL);
    171174        signal(SIGILL, SIG_DFL);
    172175        signal(SIGABRT, SIG_DFL);
    173176        signal(SIGFPE, SIG_DFL);
     
    181184        /* Quit Sage with an appropriate message. */
    182185        switch(sig)
    183186        {
    184             case SIGILL:
     187            case SIGQUIT:
     188                sigdie(sig, NULL);
     189                break;  /* This will not be reached */
     190            case SIGILL:
    185191                sigdie(sig, "Unhandled SIGILL: An illegal instruction occurred in Sage.");
    186192                break;  /* This will not be reached */
    187             case SIGABRT: 
     193            case SIGABRT:
    188194                sigdie(sig, "Unhandled SIGABRT: An abort() occurred in Sage.");
    189195                break;  /* This will not be reached */
    190             case SIGFPE: 
     196            case SIGFPE:
    191197                sigdie(sig, "Unhandled SIGFPE: An unhandled floating point exception occurred in Sage.");
    192198                break;  /* This will not be reached */
    193             case SIGBUS: 
     199            case SIGBUS:
    194200                sigdie(sig, "Unhandled SIGBUS: A bus error occurred in Sage.");
    195201                break;  /* This will not be reached */
    196             case SIGSEGV: 
     202            case SIGSEGV:
    197203                sigdie(sig, "Unhandled SIGSEGV: A segmentation fault occurred in Sage.");
    198204                break;  /* This will not be reached */
    199205        };
     
    328334    /* Allow signals during signal handling, we have code to deal with
    329335     * this case. */
    330336    sa.sa_flags |= SA_NODEFER;
     337    if (sigaction(SIGQUIT, &sa, NULL)) {perror("sigaction"); exit(1);}
    331338    if (sigaction(SIGILL, &sa, NULL)) {perror("sigaction"); exit(1);}
    332339    if (sigaction(SIGABRT, &sa, NULL)) {perror("sigaction"); exit(1);}
    333340    if (sigaction(SIGFPE, &sa, NULL)) {perror("sigaction"); exit(1);}
     
    355362}
    356363
    357364
     365static void print_sep()
     366{
     367    fprintf(stderr,
     368        "------------------------------------------------------------------------\n");
     369    fflush(stderr);
     370}
     371
    358372void print_backtrace()
    359373{
    360374    void* backtracebuffer[1024];
     
    362376#ifdef HAVE_BACKTRACE
    363377    int btsize = backtrace(backtracebuffer, 1024);
    364378    backtrace_symbols_fd(backtracebuffer, btsize, 2);
     379    print_sep();
    365380#endif
    366381}
    367382
     
    390405
    391406        snprintf(path, sizeof(path), "%s/bin/sage-CSI", getenv("SAGE_LOCAL"));
    392407        snprintf(pid_str, sizeof(pid_str), "%i", parent_pid);
    393        
     408
    394409        argv[0] = "sage-CSI";
    395410        argv[1] = "--no-color";
    396411        argv[2] = "--pid";
     
    402417    }
    403418    /* Wait for sage-CSI to finish */
    404419    waitpid(pid, NULL, 0);
     420
     421    print_sep();
    405422}
    406423
    407424
    408425void sigdie(int sig, const char* s)
    409426{
    410     fprintf(stderr,
    411         "------------------------------------------------------------------------\n");
     427    print_sep();
    412428    print_backtrace();
    413429
    414430#if ENABLE_DEBUG_INTERRUPT
     
    418434#else
    419435#ifndef __APPLE__
    420436    /* See http://trac.sagemath.org/13889 for how Apple screwed this up */
    421     fprintf(stderr,
    422         "------------------------------------------------------------------------\n");
    423437    print_enhanced_backtrace();
    424438#endif
    425439#endif
    426440
    427     fprintf(stderr,
    428         "------------------------------------------------------------------------\n"
    429         "%s\n"
    430         "This probably occurred because a *compiled* component of Sage has a bug\n"
    431         "in it and is not properly wrapped with sig_on(), sig_off(). You might\n"
    432         "want to run Sage under gdb with 'sage -gdb' to debug this.\n"
    433         "Sage will now terminate.\n"
    434         "------------------------------------------------------------------------\n",
    435         s);
    436     fflush(stderr);
     441    if (s) {
     442        fprintf(stderr,
     443            "%s\n"
     444            "This probably occurred because a *compiled* component of Sage has a bug\n"
     445            "in it and is not properly wrapped with sig_on(), sig_off().\n"
     446            "Sage will now terminate.\n", s);
     447        print_sep();
     448    }
    437449
    438450    /* Suicide with signal ``sig`` */
    439451    kill(getpid(), sig);
  • sage/doctest/test.py

    diff --git a/sage/doctest/test.py b/sage/doctest/test.py
    a b  
    174174    ------------------------------------------------------------------------
    175175    Unhandled SIGABRT: An abort() occurred in Sage.
    176176    This probably occurred because a *compiled* component of Sage has a bug
    177     in it and is not properly wrapped with sig_on(), sig_off(). You might
    178     want to run Sage under gdb with 'sage -gdb' to debug this.
     177    in it and is not properly wrapped with sig_on(), sig_off().
    179178    Sage will now terminate.
    180179    ------------------------------------------------------------------------
    181180    ...
  • sage/tests/interrupt.pyx

    diff --git a/sage/tests/interrupt.pyx b/sage/tests/interrupt.pyx
    a b  
    446446    signal_after_delay(SIGBUS, delay)
    447447    infinite_loop()
    448448
     449def test_signal_quit(long delay = DEFAULT_DELAY):
     450    """
     451    TESTS:
     452
     453    We run Sage in a subprocess and make it raise a SIGQUIT under
     454    ``sig_on()``.  This should cause Sage to exit::
     455
     456        sage: from subprocess import *
     457        sage: cmd = 'from sage.tests.interrupt import *; test_signal_quit()'
     458        sage: print Popen(['sage', '-c', cmd], stdout=PIPE, stderr=PIPE).communicate()[1]  # long time
     459        ---...---
     460    """
     461    # The sig_on() shouldn't make a difference for SIGQUIT
     462    sig_on()
     463    signal_after_delay(SIGQUIT, delay)
     464    infinite_loop()
     465
    449466
    450467########################################################################
    451468# Test with "true" errors (not signals raised by hand)                 #
     
    475492
    476493        sage: from subprocess import *
    477494        sage: cmd = 'from sage.tests.interrupt import *; unguarded_dereference_null_pointer()'
    478         sage: print '---'; print Popen(['sage', '-c', cmd], stdout=PIPE, stderr=PIPE).communicate()[1]  # long time
    479         -...
    480         ------------------------------------------------------------------------
     495        sage: print Popen(['sage', '-c', cmd], stdout=PIPE, stderr=PIPE).communicate()[1]  # long time
     496        ---...---
    481497        Unhandled SIG...
    482498        This probably occurred because a *compiled* component of Sage has a bug
    483         in it and is not properly wrapped with sig_on(), sig_off(). You might
    484         want to run Sage under gdb with 'sage -gdb' to debug this.
     499        in it and is not properly wrapped with sig_on(), sig_off().
    485500        Sage will now terminate.
    486501        ------------------------------------------------------------------------
    487502    """
     
    508523
    509524        sage: from subprocess import *
    510525        sage: cmd = 'from sage.tests.interrupt import *; unguarded_abort()'
    511         sage: print '---'; print Popen(['sage', '-c', cmd], stdout=PIPE, stderr=PIPE).communicate()[1]  # long time
    512         -...
    513         ------------------------------------------------------------------------
     526        sage: print Popen(['sage', '-c', cmd], stdout=PIPE, stderr=PIPE).communicate()[1]  # long time
     527        ---...---
    514528        Unhandled SIGABRT: An abort() occurred in Sage.
    515529        This probably occurred because a *compiled* component of Sage has a bug
    516         in it and is not properly wrapped with sig_on(), sig_off(). You might
    517         want to run Sage under gdb with 'sage -gdb' to debug this.
     530        in it and is not properly wrapped with sig_on(), sig_off().
    518531        Sage will now terminate.
    519532        ------------------------------------------------------------------------
    520533    """
     
    528541
    529542        sage: from subprocess import *
    530543        sage: cmd = 'from sage.tests.interrupt import *; test_bad_str()'
    531         sage: print '---'; print Popen(['sage', '-c', cmd], stdout=PIPE, stderr=PIPE).communicate()[1]  # long time
    532         -...
    533         ------------------------------------------------------------------------
     544        sage: print Popen(['sage', '-c', cmd], stdout=PIPE, stderr=PIPE).communicate()[1]  # long time
     545        ---...---
    534546        An error occured during signal handling.
    535547        This probably occurred because a *compiled* component of Sage has a bug
    536         in it and is not properly wrapped with sig_on(), sig_off(). You might
    537         want to run Sage under gdb with 'sage -gdb' to debug this.
     548        in it and is not properly wrapped with sig_on(), sig_off().
    538549        Sage will now terminate.
    539550        ------------------------------------------------------------------------
    540551    """