Ticket #10031: sig_except.patch

File sig_except.patch, 6.5 KB (added by jdemeyer, 10 years ago)
  • c_lib/include/interrupt.h

    diff -r 2363e71757cc c_lib/include/interrupt.h
    a b  
    2626   to get signal handling capabilities.
    2727
    2828   VERY VERY IMPORTANT: 
    29        1. These *must* always come in pairs. E.g., if you have just
    30           a _sig_off without a corresponding _sig_on, then ctrl-c
    31           later in the interpreter will sigfault!
     29       1. These *must* always come in pairs.
    3230
    3331       2. Do *not* put these in the __init__ method of a Pyrex extension
    3432          class, or you'll get crashes.
    3533
    3634       3. Do not put these around any non-pure C code!!!!
    37 
    38        4. If you need to do a check of control-c inside a loop, e.g.,
    39           when constructing a matrix, put _sig_check instead of using
    40           _sig_on then _sig_off.
    4135*/
    4236
    4337/**
     
    164158
    165159/**
    166160 * Enables SAGE signal handling for the following C block. This macro
    167  * *MUST* be followed by _sig_off.
     161 * *MUST* be followed by ``_sig_off``.
    168162 *
     163 * INPUT:
    169164 *
    170  * See also @ref _sig_str
     165 *  - ``str`` - a string to be displayed as error message when the code
     166 *    between ``_sig_on`` and ``_sig_off`` fails.
     167 *
     168 *  - ``except`` - the value to return when an exception is raised.
     169 *    This should correspond to the "except" value in the Cython
     170 *    declaration of the function.  For example, the function
     171 *    cdef int my_cython_function() except -1:
     172 *    should use ``except`` = -1.
     173 *    A function which return a Python object should NOT have an except
     174 *    declaration and should use ``except`` = 0:
     175 *    cdef function_returning_a_python_object():
     176 *
     177 * This is the most general macro, in practice you must use one of the
     178 * shortcuts macros like ``_sig_on`` defined later.
     179 *
    171180 */
    172 
    173 /* The function sigsetjmp() below can return the following:
     181#define _sig_on_str_except(str, except) \
     182    if (_signals.mpio == 0) { \
     183        _signals.mpio = 1+2; _signals.s = str;\
     184        if (sigsetjmp(_signals.env,1) > 0) { \
     185            _signals.mpio = 0;   \
     186            return(except); \
     187     } }
     188/* The function sigsetjmp() in the macro above can return the following:
    174189 *  - zero: this happens in the actual _sig_on call and sets up the
    175190 *    address for the Sage signal handler to jump to.  The program
    176191 *    continues normally.
     
    183198 *    this case, the program continues as if nothing happened between
    184199 *    _sig_on and _sig_retry.
    185200 */
    186 #define _sig_on if (_signals.mpio == 0) { _signals.mpio = 1+2; _signals.s = NULL;\
    187                  if (sigsetjmp(_signals.env,1) > 0) { \
    188                   _signals.mpio = 0;   \
    189                   return(0); \
    190                 } } // else { _signals.s = "Unbalanced _sig_on/_sig_off\n"; fprintf(stderr, _signals.s); sage_signal_handler(SIGABRT); }
    191201
    192 /* /\** */
    193 /*  * Enables SAGE signal handling for the following C block. This macro */
    194 /*  * *MUST* be followed by _sig_off_short. */
    195 /*  * */
    196 /*  * If the following block takes very little time to compute this macro */
    197 /*  * is the right choice. Otherwise _sig_on is appropriate. */
    198 /*  * */
    199 /*  * See also _sig_on and _sig_str. */
    200 /*  * */
    201 /*  *\/ */
    202202
    203 /* #define _sig_on_short _signals.mpio = 1 */
    204 
    205 
    206 /**
    207  * Same as @ref _sig_on but with string support
    208  *
    209  */
    210  
    211 #define _sig_str(mstring) if (_signals.mpio == 0) { _signals.mpio = 1+2; \
    212                 _signals.s = mstring; \
    213                 if (sigsetjmp(_signals.env,1) > 0) { \
    214                   _signals.mpio = 0; \
    215                  return(0); \
    216                 } } //else { _signals.s = "Unbalanced _sig_str/_sig_off\n"; fprintf(stderr, _signals.s); sage_signal_handler(SIGABRT); }
     203/* Some very useful shortcuts.
     204 * Note that we need to define the except values with a type in
     205 * sage/ext/interrupt.pxi, but we can define the macros the same
     206 * regardless of the type. */
     207#define _sig_on _sig_on_str_except(NULL, 0)
     208#define _sig_str(str) _sig_on_str_except(str, 0)
     209#define _sig_on_except_int(except) _sig_on_str_except(NULL, except)
     210#define _sig_str_except_int(str, except) _sig_on_str_except(str, except)
    217211
    218212
    219213/*
     
    229223#define SAGE_SIGNAL_HANDLER_MESSAGE_LEN 256
    230224
    231225
    232 /**
    233  *
    234  *
    235  */
    236 
    237226#define _sig_off _signals.mpio = 0;
    238227
    239228
    240 /* /\** */
    241 /*  * */
    242 /*  * */
    243 /*  *\/ */
    244 
    245 /* #define _sig_off_short (_signals.mpio & 4) */
    246 
    247 
    248 /**
    249  *
    250  *
    251  */
    252 
    253 #define _sig_check _sig_on _sig_off
    254229
    255230/* Retry a failed computation starting from the last _sig_on.  The
    256231 * program will continue as if nothing happened between _sig_on and
  • c_lib/src/interrupt.c

    diff -r 2363e71757cc c_lib/src/interrupt.c
    a b  
    1212#include "stdsage.h"
    1313#include "interrupt.h"
    1414#include <stdio.h>
     15#include <execinfo.h>
    1516
    1617
    1718char sage_signal_handler_message[SAGE_SIGNAL_HANDLER_MESSAGE_LEN + 1] = "";
     
    2930void msg(char* s);
    3031
    3132void sage_signal_handler(int sig) {
     33  void* backtracebuffer[1024];
    3234
    3335  char *s = _signals.s;
    3436  _signals.s = NULL;
     
    3840  {
    3941     s = sage_signal_handler_message;
    4042  }
     43 
     44  if (sig == SIGINT)
     45  {
     46    fprintf(stderr, "\n*** SIGINT *** %s _sig_on\n",  (_signals.mpio & 1) ? "inside" : "outside");
     47    int btsize = backtrace(backtracebuffer, 1024);
     48    backtrace_symbols_fd(backtracebuffer, btsize, 2);
     49    fflush(stderr);
     50  }
    4151
    4252  //we override the default handler
    4353  if ( _signals.mpio & 1 ) {
     
    104114      break;
    105115    default:
    106116      _signals.python_handler(sig);
     117      fprintf(stderr, "*** Python signal handler finished\n"); fflush(stderr);
    107118      break;
    108119    };
    109120   
  • sage/ext/interrupt.pxi

    diff -r 2363e71757cc sage/ext/interrupt.pxi
    a b  
    55################################################################
    66
    77cdef extern from 'interrupt.h':
    8     int _sig_on, _sig_off, _sig_check, _sig_retry
    9     void _sig_str(char*)
     8    int _sig_on
     9    int _sig_str(char*)
     10    int _sig_on_except_int(int)
     11    int _sig_str_except_int(char*, int)
     12    int _sig_off, _sig_retry
  • sage/libs/singular/polynomial.pyx

    diff -r 2363e71757cc sage/libs/singular/polynomial.pyx
    a b  
    314314    if(r != currRing): rChangeCurrRing(r)
    315315    cdef int count = singular_polynomial_length_bounded(p,15)
    316316    if count >= 15 or exp > 15:
    317         _sig_on
     317        _sig_on_except_int(-1)
    318318    ret[0] = pPower( p_Copy(p,r), exp)
    319319    if count >= 15 or exp > 15:
    320320        _sig_off