Actual source code: signal.c

petsc-master 2019-08-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: @*/
 60: PetscErrorCode  PetscSignalHandlerDefault(int sig,void *ptr)
 61: {
 63:   const char     *SIGNAME[64];

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

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

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

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

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

164:    Not Collective

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

170:   Level: developer

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

174: @*/
175: PetscErrorCode  PetscPushSignalHandler(PetscErrorCode (*routine)(int,void*),void *ctx)
176: {
177:   struct  SH     *newsh;

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

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

319:    Not Collective

321:   Level: developer

323: .seealso: PetscPushSignalHandler()

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

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

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