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 petsc.h
  7: #include <signal.h>
 8:  #include petscsys.h
  9: #include "petscfix.h"     

 11: static PetscCookie SIGNAL_COOKIE = 0;

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



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


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

 51:   if (!sh || !sh->handler) {
 52:     PetscDefaultSignalHandler(sig,(void*)0);
 53:   } else{
 54:     if (sh->cookie != SIGNAL_COOKIE) SETERRABORT(PETSC_COMM_WORLD,PETSC_ERR_COR,"Signal object has been corrupted");
 55:     (*sh->handler)(sig,sh->ctx);
 56:   }
 57:   if (ierr) MPI_Abort(PETSC_COMM_WORLD,0);
 58: }

 63: /*@
 64:    PetscDefaultSignalHandler - Default signal handler.

 66:    Not Collective

 68:    Level: advanced

 70:    Input Parameters:
 71: +  sig - signal value
 72: -  ptr - unused pointer

 74:    Concepts: signal handler^default

 76: @*/
 77: PetscErrorCode  PetscDefaultSignalHandler(int sig,void *ptr)
 78: {
 80:   const char     *SIGNAME[64];

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

145:   signal(sig,SIG_DFL);
146:     (*PetscErrorPrintf)("------------------------------------------------------------------------\n");
147:   if (sig >= 0 && sig <= 20) {
148:     (*PetscErrorPrintf)("Caught signal number %d %s\n",sig,SIGNAME[sig]);
149:   } else {
150:     (*PetscErrorPrintf)("Caught signal\n");
151:   }
152:   (*PetscErrorPrintf)("Try option -start_in_debugger or -on_error_attach_debugger\n");
153:   (*PetscErrorPrintf)("or see http://www.mcs.anl.gov/petsc/petsc-as/documentation/troubleshooting.html#Signal");
154:   (*PetscErrorPrintf)("or try http://valgrind.org on linux or man libgmalloc on Apple to find memory corruption errors\n");
155: #if defined(PETSC_USE_DEBUG)
156:   if (!PetscStackActive) {
157:     (*PetscErrorPrintf)("  or try option -log_stack\n");
158:   } else {
159:     PetscStackPop;  /* remove stack frames for error handlers */
160:     PetscStackPop;
161:     (*PetscErrorPrintf)("likely location of problem given in stack below\n");
162:     (*PetscErrorPrintf)("---------------------  Stack Frames ------------------------------------\n");
163:     PetscStackView(PETSC_VIEWER_STDOUT_SELF);
164:   }
165: #endif
166: #if !defined(PETSC_USE_DEBUG)
167:   (*PetscErrorPrintf)("configure using --with-debugging=yes, recompile, link, and run \n");
168:   (*PetscErrorPrintf)("to get more information on the crash.\n");
169: #endif
170:    PetscError(0,"User provided function"," unknown file","unknown directory",PETSC_ERR_SIG,1,PETSC_NULL);
171:   MPI_Abort(PETSC_COMM_WORLD,(int)ierr);
172:   return(0);
173: }

175: #if !defined(PETSC_SIGNAL_CAST)
176: #define PETSC_SIGNAL_CAST
177: #endif

181: /*@C
182:    PetscPushSignalHandler - Catches the usual fatal errors and 
183:    calls a user-provided routine.

185:    Not Collective

187:     Input Parameter:
188: +  routine - routine to call when a signal is received
189: -  ctx - optional context needed by the routine

191:   Level: developer

193:    Concepts: signal handler^setting

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

197: @*/
198: PetscErrorCode  PetscPushSignalHandler(PetscErrorCode (*routine)(int,void*),void* ctx)
199: {
200:   struct  SH     *newsh;

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

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

337:    Not Collective

339:   Level: developer

341:    Concepts: signal handler^setting

343: .seealso: PetscPushSignalHandler()

345: @*/
346: PetscErrorCode  PetscPopSignalHandler(void)
347: {
348:   struct SH *tmp;

351:   if (!sh) return(0);
352:   if (sh->cookie != SIGNAL_COOKIE) SETERRQ(PETSC_ERR_COR,"Signal object has been corrupted");

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