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

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

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

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

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

    166:    Not Collective

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

    172:   Level: developer

    174:    Concepts: signal handler^setting

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

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

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

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

    315:    Not Collective

    317:   Level: developer

    319:    Concepts: signal handler^setting

    321: .seealso: PetscPushSignalHandler()

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

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

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