Actual source code: signal.c

petsc-3.3-p7 2013-05-11
  2: /*
  3:       Routines to handle signals the program will receive. 
  4:     Usually this will call the error handlers.
  5: */
  6: #include <petscsys.h>             /*I   "petscsys.h"   I*/
  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;



 22: EXTERN_C_BEGIN
 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 - ??

 35:     Note: this is declared extern "C" because it is passed to the system routine signal()
 36:           which is an extern "C" routine. The Solaris 2.7 OS compilers require that this be
 37:           extern "C".

 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:     if (sh->classid != SIGNAL_CLASSID) SETERRABORT(PETSC_COMM_WORLD,PETSC_ERR_COR,"Signal object has been corrupted");
 53:     (*sh->handler)(sig,sh->ctx);
 54:   }
 55:   if (ierr) MPI_Abort(PETSC_COMM_WORLD,0);
 56: }
 57: EXTERN_C_END

 61: /*@
 62:    PetscDefaultSignalHandler - Default signal handler.

 64:    Not Collective

 66:    Level: advanced

 68:    Input Parameters:
 69: +  sig - signal value
 70: -  ptr - unused pointer

 72:    Concepts: signal handler^default

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

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

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

173: #if !defined(PETSC_SIGNAL_CAST)
174: #define PETSC_SIGNAL_CAST
175: #endif

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

183:    Not Collective

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

189:   Level: developer

191:    Concepts: signal handler^setting

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

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

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

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

335:    Not Collective

337:   Level: developer

339:    Concepts: signal handler^setting

341: .seealso: PetscPushSignalHandler()

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

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

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