Actual source code: signal.c

      1: #define PETSC_DLL
      2: /*
      3:       Routines to handle signals the program will receive.
      4:     Usually this will call the error handlers.
      5: */
      6: #include <signal.h>
     7:  #include petsc.h
     8:  #include petscsys.h
      9: #include "petscfix.h"

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

     25: /*
     26:     PetscSignalHandler_Private - This is the signal handler called by the system. This calls
     27:              any signal handler set by PETSc or the application code.
     28:
     29:    Input Parameters: (depends on system)
     30: .    sig - integer code indicating the type of signal
     31: .    code - ??
     32: .    sigcontext - ??
     33: .    addr - ??

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

     49:   if (!sh || !sh->handler) {
     50:     PetscDefaultSignalHandler(sig,(void*)0);
     51:   } else{
     52:     (*sh->handler)(sig,sh->ctx);
     53:   }
     54:   if (ierr) MPI_Abort(PETSC_COMM_WORLD,0);
     55: }

     60: /*@
     61:    PetscDefaultSignalHandler - Default signal handler.

     63:    Not Collective

     65:    Level: advanced

     67:    Input Parameters:
     68: +  sig - signal value
     69: -  ptr - unused pointer

     71:    Concepts: signal handler^default

     73: @*/
     74: PetscErrorCode PETSC_DLLEXPORT PetscDefaultSignalHandler(int sig,void *ptr)
     75: {
     77:   const char  *SIGNAME[64];

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

    142:   signal(sig,SIG_DFL);
    143:   if (sig >= 0 && sig <= 20) {
    144:     (*PetscErrorPrintf)("Caught signal number %d %s\n",sig,SIGNAME[sig]);
    145:   } else {
    146:     (*PetscErrorPrintf)("Caught signal\n");
    147:   }
    148:   (*PetscErrorPrintf)("Try option -start_in_debugger or -on_error_attach_debugger\n");
    149: #if defined(PETSC_USE_DEBUG)
    150:   if (!PetscStackActive) {
    151:     (*PetscErrorPrintf)("  or try option -log_stack\n");
    152:   } else {
    153:     PetscStackPop;  /* remove stack frames for error handlers */
    154:     PetscStackPop;
    155:     (*PetscErrorPrintf)("likely location of problem given in stack below\n");
    156:     (*PetscErrorPrintf)("--------------- Stack Frames ---------------\n");
    157:     PetscStackView(PETSC_VIEWER_STDOUT_SELF);
    158:     (*PetscErrorPrintf)("--------------------------------------------\n");
    159:   }
    160: #endif
    161: #if !defined(PETSC_USE_DEBUG)
    162:   (*PetscErrorPrintf)("configure using --with-debugging=yes, recompile, link, and run \n");
    163:   (*PetscErrorPrintf)("to get more information on the crash.\n");
    164: #endif
    165:    PetscError(0,"User provided function"," unknown file","unknown directory",PETSC_ERR_SIG,1," ");
    166:   MPI_Abort(PETSC_COMM_WORLD,(int)ierr);
    167:   return(0);
    168: }

    170: #if !defined(PETSC_SIGNAL_CAST)
    171: #define PETSC_SIGNAL_CAST
    172: #endif

    176: /*@C
    177:    PetscPushSignalHandler - Catches the usual fatal errors and
    178:    calls a user-provided routine.

    180:    Not Collective

    182:     Input Parameter:
    183: +  routine - routine to call when a signal is received
    184: -  ctx - optional context needed by the routine

    186:   Level: developer

    188:    Concepts: signal handler^setting

    190: .seealso: PetscPopSignalHandler(), PetscDefaultSignalHandler()

    192: @*/
    193: PetscErrorCode PETSC_DLLEXPORT PetscPushSignalHandler(PetscErrorCode (*routine)(int,void*),void* ctx)
    194: {
    195:   struct  SH *newsh;

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

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

    324:    Not Collective

    326:   Level: developer

    328:    Note: NO ERROR CODES RETURNED BY THIS FUNCTION

    330:    Concepts: signal handler^setting

    332: .seealso: PetscPushSignalHandler()

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

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