Actual source code: signal.c
petsc-3.10.3 2018-12-18
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>
      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;

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

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

     30: */
     31: #if defined(PETSC_HAVE_4ARG_SIGNAL_HANDLER)
     32: static void PetscSignalHandler_Private(int sig,int code,struct sigcontext * scp,char *addr)
     33: #else
     34: static void PetscSignalHandler_Private(int sig)
     35: #endif
     36: {

     40:   if (!sh || !sh->handler) PetscSignalHandlerDefault(sig,(void*)0);
     41:   else {
     42:     if (sh->classid != SIGNAL_CLASSID) SETERRABORT(PETSC_COMM_WORLD,PETSC_ERR_COR,"Signal object has been corrupted");
     43:     (*sh->handler)(sig,sh->ctx);
     44:   }
     45:   if (ierr) MPI_Abort(PETSC_COMM_WORLD,0);
     46: }

     48: /*@
     49:    PetscSignalHandlerDefault - Default signal handler.

     51:    Not Collective

     53:    Level: advanced

     55:    Input Parameters:
     56: +  sig - signal value
     57: -  ptr - unused pointer

     59:    Concepts: signal handler^default

     61: @*/
     62: PetscErrorCode  PetscSignalHandlerDefault(int sig,void *ptr)
     63: {
     65:   const char     *SIGNAME[64];

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

    130:   signal(sig,SIG_DFL);
    131:   (*PetscErrorPrintf)("------------------------------------------------------------------------\n");
    132:   if (sig >= 0 && sig <= 20) (*PetscErrorPrintf)("Caught signal number %d %s\n",sig,SIGNAME[sig]);
    133:   else (*PetscErrorPrintf)("Caught signal\n");

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

    157: #if !defined(PETSC_SIGNAL_CAST)
    158: #define PETSC_SIGNAL_CAST
    159: #endif

    161: /*@C
    162:    PetscPushSignalHandler - Catches the usual fatal errors and
    163:    calls a user-provided routine.

    165:    Not Collective

    167:     Input Parameter:
    168: +  routine - routine to call when a signal is received
    169: -  ctx - optional context needed by the routine

    171:   Level: developer

    173:    Concepts: signal handler^setting

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

    177: @*/
    178: PetscErrorCode  PetscPushSignalHandler(PetscErrorCode (*routine)(int,void*),void *ctx)
    179: {
    180:   struct  SH     *newsh;

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

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

    314:    Not Collective

    316:   Level: developer

    318:    Concepts: signal handler^setting

    320: .seealso: PetscPushSignalHandler()

    322: @*/
    323: PetscErrorCode  PetscPopSignalHandler(void)
    324: {
    325:   struct SH      *tmp;

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

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

    395: #if defined(PETSC_HAVE_SETJMP_H) && defined(PETSC_HAVE_SIGINFO_T)
    396: #include <setjmp.h>
    397: PETSC_VISIBILITY_INTERNAL jmp_buf PetscSegvJumpBuf;
    398: /*
    399:     This routine is called if a segmentation violation, i.e. inaccessible memory access

    402:     It simply unrolls the UNIX signal and returns to the location where setjump(PetscSeqvJumpBuf) is declared.
    403: */
    404: PETSC_INTERN void PetscSegv_sigaction(int signal, siginfo_t *si, void *arg)
    405: {
    406:   longjmp(PetscSegvJumpBuf,1);
    407:   return;
    408: }
    409: #endif