Actual source code: signal.c

petsc-master 2020-06-03
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       = NULL;
 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) PETSCABORT(PETSC_COMM_WORLD,PETSC_ERR_COR);
 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) PetscSignalSegvCheckPointerOrMpi();
 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 (PetscDefined(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:   } else {
147:     (*PetscErrorPrintf)("configure using --with-debugging=yes, recompile, link, and run \n");
148:     (*PetscErrorPrintf)("to get more information on the crash.\n");
149:   }
150:    PetscError(PETSC_COMM_SELF,0,"User provided function"," unknown file",PETSC_ERR_SIG,PETSC_ERROR_INITIAL,NULL);
151:   PETSCABORT(PETSC_COMM_WORLD,(int)ierr);
152:   return(0);
153: }

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

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

163:    Not Collective

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

169:   Level: developer

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

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

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

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

318:    Not Collective

320:   Level: developer

322: .seealso: PetscPushSignalHandler()

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

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

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