Actual source code: signal.c

petsc-3.10.2 2018-10-09
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