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: }