Actual source code: signal.c
petsc-3.7.1 2016-05-15
Report Typos and Errors

      2: /*
      3:       Routines to handle signals the program will receive.
      4:     Usually this will call the error handlers.
      5: */
      6: #include <petsc/private/petscimpl.h>             /*I   "petscsys.h"   I*/
      7: #include <signal.h>

      9: static PetscClassId SIGNAL_CLASSID = 0;

     11: struct SH {
     12:   PetscClassId   classid;
     13:   PetscErrorCode (*handler)(int,void*);
     14:   void           *ctx;
     15:   struct SH      *previous;
     16: };
     17: static struct SH *sh       = 0;
     18: static PetscBool SignalSet = PETSC_FALSE;

     22: /*
     23:     PetscSignalHandler_Private - This is the signal handler called by the system. This calls
     24:              any signal handler set by PETSc or the application code.

     26:    Input Parameters: (depends on system)
     27: .    sig - integer code indicating the type of signal
     28: .    code - ??
     29: .    sigcontext - ??
     30: .    addr - ??

     32:     Note: this is declared extern "C" because it is passed to the system routine signal()
     33:           which is an extern "C" routine. The Solaris 2.7 OS compilers require that this be
     34:           extern "C".

     36: */
     37: #if defined(PETSC_HAVE_4ARG_SIGNAL_HANDLER)
     38: static void PetscSignalHandler_Private(int sig,int code,struct sigcontext * scp,char *addr)
     39: #else
     40: static void PetscSignalHandler_Private(int sig)
     41: #endif
     42: {

     46:   if (!sh || !sh->handler) PetscSignalHandlerDefault(sig,(void*)0);
     47:   else {
     48:     if (sh->classid != SIGNAL_CLASSID) SETERRABORT(PETSC_COMM_WORLD,PETSC_ERR_COR,"Signal object has been corrupted");
     49:     (*sh->handler)(sig,sh->ctx);
     50:   }
     51:   if (ierr) MPI_Abort(PETSC_COMM_WORLD,0);
     52: }

     56: /*@
     57:    PetscSignalHandlerDefault - Default signal handler.

     59:    Not Collective

     61:    Level: advanced

     63:    Input Parameters:
     64: +  sig - signal value
     65: -  ptr - unused pointer

     67:    Concepts: signal handler^default

     69: @*/
     70: PetscErrorCode  PetscSignalHandlerDefault(int sig,void *ptr)
     71: {
     73:   const char     *SIGNAME[64];

     76:   SIGNAME[0]       = "Unknown signal";
     77: #if !defined(PETSC_MISSING_SIGABRT)
     78:   SIGNAME[SIGABRT] = "Abort";
     79: #endif
     80: #if !defined(PETSC_MISSING_SIGALRM)
     81:   SIGNAME[SIGALRM] = "Alarm";
     82: #endif
     83: #if !defined(PETSC_MISSING_SIGBUS)
     84:   SIGNAME[SIGBUS]  = "BUS: Bus Error, possibly illegal memory access";
     85: #endif
     86: #if !defined(PETSC_MISSING_SIGCHLD)
     87:   SIGNAME[SIGCHLD] = "CHLD";
     88: #endif
     89: #if !defined(PETSC_MISSING_SIGCONT)
     90:   SIGNAME[SIGCONT] = "CONT";
     91: #endif
     92: #if !defined(PETSC_MISSING_SIGFPE)
     93:   SIGNAME[SIGFPE]  = "FPE: Floating Point Exception,probably divide by zero";
     94: #endif
     95: #if !defined(PETSC_MISSING_SIGHUP)
     96:   SIGNAME[SIGHUP]  = "Hang up: Some other process (or the batch system) has told this process to end";
     97: #endif
     98: #if !defined(PETSC_MISSING_SIGILL)
     99:   SIGNAME[SIGILL]  = "Illegal instruction: Likely due to memory corruption";
    100: #endif
    101: #if !defined(PETSC_MISSING_SIGINT)
    102:   SIGNAME[SIGINT]  = "Interrupt";
    103: #endif
    104: #if !defined(PETSC_MISSING_SIGKILL)
    105:   SIGNAME[SIGKILL] = "Kill: Some other process (or the batch system) has told this process to end";
    106: #endif
    107: #if !defined(PETSC_MISSING_SIGPIPE)
    108:   SIGNAME[SIGPIPE] = "Broken Pipe: Likely while reading or writing to a socket";
    109: #endif
    110: #if !defined(PETSC_MISSING_SIGQUIT)
    111:   SIGNAME[SIGQUIT] = "Quit: Some other process (or the batch system) has told this process to end";
    112: #endif
    113: #if !defined(PETSC_MISSING_SIGSEGV)
    114:   SIGNAME[SIGSEGV] = "SEGV: Segmentation Violation, probably memory access out of range";
    115: #endif
    116: #if !defined(PETSC_MISSING_SIGSYS)
    117:   SIGNAME[SIGSYS]  = "SYS";
    118: #endif
    119: #if !defined(PETSC_MISSING_SIGTERM)
    120:   SIGNAME[SIGTERM] = "Terminate: Some process (or the batch system) has told this process to end";
    121: #endif
    122: #if !defined(PETSC_MISSING_SIGTRAP)
    123:   SIGNAME[SIGTRAP] = "TRAP";
    124: #endif
    125: #if !defined(PETSC_MISSING_SIGTSTP)
    126:   SIGNAME[SIGTSTP] = "TSTP";
    127: #endif
    128: #if !defined(PETSC_MISSING_SIGURG)
    129:   SIGNAME[SIGURG]  = "URG";
    130: #endif
    131: #if !defined(PETSC_MISSING_SIGUSR1)
    132:   SIGNAME[SIGUSR1] = "User 1";
    133: #endif
    134: #if !defined(PETSC_MISSING_SIGUSR2)
    135:   SIGNAME[SIGUSR2] = "User 2";
    136: #endif

    138:   signal(sig,SIG_DFL);
    139:   (*PetscErrorPrintf)("------------------------------------------------------------------------\n");
    140:   if (sig >= 0 && sig <= 20) (*PetscErrorPrintf)("Caught signal number %d %s\n",sig,SIGNAME[sig]);
    141:   else (*PetscErrorPrintf)("Caught signal\n");

    143:   (*PetscErrorPrintf)("Try option -start_in_debugger or -on_error_attach_debugger\n");
    144:   (*PetscErrorPrintf)("or see http://www.mcs.anl.gov/petsc/documentation/faq.html#valgrind\n");
    145:   (*PetscErrorPrintf)("or try http://valgrind.org on GNU/linux and Apple Mac OS X to find memory corruption errors\n");
    146: #if defined(PETSC_USE_DEBUG)
    147:   if (!PetscStackActive()) (*PetscErrorPrintf)("  or try option -log_stack\n");
    148:   else {
    149:     PetscStackPop;  /* remove stack frames for error handlers */
    150:     PetscStackPop;
    151:     (*PetscErrorPrintf)("likely location of problem given in stack below\n");
    152:     (*PetscErrorPrintf)("---------------------  Stack Frames ------------------------------------\n");
    153:     PetscStackView(PETSC_STDOUT);
    154:   }
    155: #endif
    156: #if !defined(PETSC_USE_DEBUG)
    157:   (*PetscErrorPrintf)("configure using --with-debugging=yes, recompile, link, and run \n");
    158:   (*PetscErrorPrintf)("to get more information on the crash.\n");
    159: #endif
    160:    PetscError(PETSC_COMM_SELF,0,"User provided function"," unknown file",PETSC_ERR_SIG,PETSC_ERROR_INITIAL,NULL);
    161:   MPI_Abort(PETSC_COMM_WORLD,(int)ierr);
    162:   return(0);
    163: }

    165: #if !defined(PETSC_SIGNAL_CAST)
    166: #define PETSC_SIGNAL_CAST
    167: #endif

    171: /*@C
    172:    PetscPushSignalHandler - Catches the usual fatal errors and
    173:    calls a user-provided routine.

    175:    Not Collective

    177:     Input Parameter:
    178: +  routine - routine to call when a signal is received
    179: -  ctx - optional context needed by the routine

    181:   Level: developer

    183:    Concepts: signal handler^setting

    185: .seealso: PetscPopSignalHandler(), PetscSignalHandlerDefault(), PetscPushErrorHandler()

    187: @*/
    188: PetscErrorCode  PetscPushSignalHandler(PetscErrorCode (*routine)(int,void*),void *ctx)
    189: {
    190:   struct  SH     *newsh;

    194:   if (!SIGNAL_CLASSID) {
    195:     /* PetscClassIdRegister("Signal",&SIGNAL_CLASSID); */
    196:     SIGNAL_CLASSID = 19;
    197:   }
    198:   if (!SignalSet && routine) {
    199:     /* Do not catch ABRT, CHLD, KILL */
    200: #if !defined(PETSC_MISSING_SIGALRM)
    201:     /* signal(SIGALRM, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */
    202: #endif
    203: #if !defined(PETSC_MISSING_SIGBUS)
    204:     signal(SIGBUS, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
    205: #endif
    206: #if !defined(PETSC_MISSING_SIGCONT)
    207:     /*signal(SIGCONT, PETSC_SIGNAL_CAST PetscSignalHandler_Private);*/
    208: #endif
    209: #if !defined(PETSC_MISSING_SIGFPE)
    210:     signal(SIGFPE,  PETSC_SIGNAL_CAST PetscSignalHandler_Private);
    211: #endif
    212: #if !defined(PETSC_MISSING_SIGHUP)
    213:     signal(SIGHUP, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
    214: #endif
    215: #if !defined(PETSC_MISSING_SIGILL)
    216:     signal(SIGILL,  PETSC_SIGNAL_CAST PetscSignalHandler_Private);
    217: #endif
    218: #if !defined(PETSC_MISSING_SIGINT)
    219:     /* signal(SIGINT, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */
    220: #endif
    221: #if !defined(PETSC_MISSING_SIGPIPE)
    222:     signal(SIGPIPE, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
    223: #endif
    224: #if !defined(PETSC_MISSING_SIGQUIT)
    225:     signal(SIGQUIT, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
    226: #endif
    227: #if !defined(PETSC_MISSING_SIGSEGV)
    228:     signal(SIGSEGV, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
    229: #endif
    230: #if !defined(PETSC_MISSING_SIGSYS)
    231:     signal(SIGSYS,  PETSC_SIGNAL_CAST PetscSignalHandler_Private);
    232: #endif
    233: #if !defined(PETSC_MISSING_SIGTERM)
    234:     signal(SIGTERM,  PETSC_SIGNAL_CAST PetscSignalHandler_Private);
    235: #endif
    236: #if !defined(PETSC_MISSING_SIGTRAP)
    237:     signal(SIGTRAP,  PETSC_SIGNAL_CAST PetscSignalHandler_Private);
    238: #endif
    239: #if !defined(PETSC_MISSING_SIGTSTP)
    240:     /* signal(SIGTSTP,  PETSC_SIGNAL_CAST PetscSignalHandler_Private); */
    241: #endif
    242: #if !defined(PETSC_MISSING_SIGURG)
    243:     signal(SIGURG,  PETSC_SIGNAL_CAST PetscSignalHandler_Private);
    244: #endif
    245: #if !defined(PETSC_MISSING_SIGUSR1)
    246:     /*    signal(SIGUSR1, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */
    247: #endif
    248: #if !defined(PETSC_MISSING_SIGUSR2)
    249:     /* signal(SIGUSR2, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */
    250: #endif
    251:     SignalSet = PETSC_TRUE;
    252:   }
    253:   if (!routine) {
    254: #if !defined(PETSC_MISSING_SIGALRM)
    255:     /* signal(SIGALRM, 0); */
    256: #endif
    257: #if !defined(PETSC_MISSING_SIGBUS)
    258:     signal(SIGBUS,  0);
    259: #endif
    260: #if !defined(PETSC_MISSING_SIGCONT)
    261:     /* signal(SIGCONT, 0); */
    262: #endif
    263: #if !defined(PETSC_MISSING_SIGFPE)
    264:     signal(SIGFPE,  0);
    265: #endif
    266: #if !defined(PETSC_MISSING_SIGHUP)
    267:     signal(SIGHUP,  0);
    268: #endif
    269: #if !defined(PETSC_MISSING_SIGILL)
    270:     signal(SIGILL,  0);
    271: #endif
    272: #if !defined(PETSC_MISSING_SIGINT)
    273:     /* signal(SIGINT,  0); */
    274: #endif
    275: #if !defined(PETSC_MISSING_SIGPIPE)
    276:     signal(SIGPIPE, 0);
    277: #endif
    278: #if !defined(PETSC_MISSING_SIGQUIT)
    279:     signal(SIGQUIT, 0);
    280: #endif
    281: #if !defined(PETSC_MISSING_SIGSEGV)
    282:     signal(SIGSEGV, 0);
    283: #endif
    284: #if !defined(PETSC_MISSING_SIGSYS)
    285:     signal(SIGSYS,  0);
    286: #endif
    287: #if !defined(PETSC_MISSING_SIGTERM)
    288:     signal(SIGTERM, 0);
    289: #endif
    290: #if !defined(PETSC_MISSING_SIGTRAP)
    291:     signal(SIGTRAP, 0);
    292: #endif
    293: #if !defined(PETSC_MISSING_SIGTSTP)
    294:     /* signal(SIGTSTP, 0); */
    295: #endif
    296: #if !defined(PETSC_MISSING_SIGURG)
    297:     signal(SIGURG,  0);
    298: #endif
    299: #if !defined(PETSC_MISSING_SIGUSR1)
    300:     /*    signal(SIGUSR1, 0); */
    301: #endif
    302: #if !defined(PETSC_MISSING_SIGUSR2)
    303:     /* signal(SIGUSR2, 0); */
    304: #endif
    305:     SignalSet = PETSC_FALSE;
    306:   }
    307:   PetscNew(&newsh);
    308:   if (sh) {
    309:     if (sh->classid != SIGNAL_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_COR,"Signal object has been corrupted");
    310:     newsh->previous = sh;
    311:   }  else newsh->previous = 0;
    312:   newsh->handler = routine;
    313:   newsh->ctx     = ctx;
    314:   newsh->classid = SIGNAL_CLASSID;
    315:   sh             = newsh;
    316:   return(0);
    317: }

    321: /*@
    322:    PetscPopSignalHandler - Removes the most last signal handler that was pushed.
    323:        If no signal handlers are left on the stack it will remove the PETSc signal handler.
    324:        (That is PETSc will no longer catch signals).

    326:    Not Collective

    328:   Level: developer

    330:    Concepts: signal handler^setting

    332: .seealso: PetscPushSignalHandler()

    334: @*/
    335: PetscErrorCode  PetscPopSignalHandler(void)
    336: {
    337:   struct SH *tmp;

    340:   if (!sh) return(0);
    341:   if (sh->classid != SIGNAL_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_COR,"Signal object has been corrupted");

    343:   tmp = sh;
    344:   sh  = sh->previous;
    345:   PetscFreeVoid(tmp);
    346:   if (!sh || !sh->handler) {
    347: #if !defined(PETSC_MISSING_SIGALRM)
    348:     /* signal(SIGALRM, 0); */
    349: #endif
    350: #if !defined(PETSC_MISSING_SIGBUS)
    351:     signal(SIGBUS,  0);
    352: #endif
    353: #if !defined(PETSC_MISSING_SIGCONT)
    354:     /* signal(SIGCONT, 0); */
    355: #endif
    356: #if !defined(PETSC_MISSING_SIGFPE)
    357:     signal(SIGFPE,  0);
    358: #endif
    359: #if !defined(PETSC_MISSING_SIGHUP)
    360:     signal(SIGHUP,  0);
    361: #endif
    362: #if !defined(PETSC_MISSING_SIGILL)
    363:     signal(SIGILL,  0);
    364: #endif
    365: #if !defined(PETSC_MISSING_SIGINT)
    366:     /* signal(SIGINT,  0); */
    367: #endif
    368: #if !defined(PETSC_MISSING_SIGPIPE)
    369:     signal(SIGPIPE, 0);
    370: #endif
    371: #if !defined(PETSC_MISSING_SIGQUIT)
    372:     signal(SIGQUIT, 0);
    373: #endif
    374: #if !defined(PETSC_MISSING_SIGSEGV)
    375:     signal(SIGSEGV, 0);
    376: #endif
    377: #if !defined(PETSC_MISSING_SIGSYS)
    378:     signal(SIGSYS,  0);
    379: #endif
    380: #if !defined(PETSC_MISSING_SIGTERM)
    381:     signal(SIGTERM, 0);
    382: #endif
    383: #if !defined(PETSC_MISSING_SIGTRAP)
    384:     signal(SIGTRAP, 0);
    385: #endif
    386: #if !defined(PETSC_MISSING_SIGTSTP)
    387:     /* signal(SIGTSTP, 0); */
    388: #endif
    389: #if !defined(PETSC_MISSING_SIGURG)
    390:     signal(SIGURG,  0);
    391: #endif
    392: #if !defined(PETSC_MISSING_SIGUSR1)
    393:     /*    signal(SIGUSR1, 0); */
    394: #endif
    395: #if !defined(PETSC_MISSING_SIGUSR2)
    396:     /* signal(SIGUSR2, 0); */
    397: #endif
    398:     SignalSet = PETSC_FALSE;
    399:   } else {
    400:     SignalSet = PETSC_TRUE;
    401:   }
    402:   return(0);
    403: }

    406: #if defined(PETSC_HAVE_SETJMP_H) && defined(PETSC_HAVE_SIGINFO_T)
    407: #include <setjmp.h>
    408: PETSC_VISIBILITY_INTERNAL jmp_buf PetscSegvJumpBuf;
    409: /*
    410:     This routine is called if a segmentation violation, i.e. inaccessible memory access

    413:     It simply unrolls the UNIX signal and returns to the location where setjump(PetscSeqvJumpBuf) is declared.
    414: */
    415: PETSC_INTERN void PetscSegv_sigaction(int signal, siginfo_t *si, void *arg)
    416: {
    417:   longjmp(PetscSegvJumpBuf,1);
    418:   return;
    419: }
    420: #endif