Actual source code: signal.c

  1: /*$Id: signal.c,v 1.80 2001/04/23 15:47:54 bsmith Exp $*/
  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:   int    (*handler)(int,void *);
 14:   void   *ctx;
 15:   struct SH* previous;
 16: };
 17: static struct SH* sh        = 0;
 18: static PetscTruth 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:     (*sh->handler)(sig,sh->ctx);
 53:   }
 54:   if (ierr) MPI_Abort(PETSC_COMM_WORLD,0);
 55: }
 56: EXTERN_C_END

 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: int PetscDefaultSignalHandler(int sig,void *ptr)
 75: {
 76:   int         ierr;
 77:   static char buf[1024];
 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: \nPETSC ERROR: 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:\nPETSC ERROR: Floating Point Exception,probably divide by zero";
 99: #endif
100: #if !defined(PETSC_MISSING_SIGHUP)
101:   SIGNAME[SIGHUP]  = "Hang up";
102: #endif
103: #if !defined(PETSC_MISSING_SIGILL)
104:   SIGNAME[SIGILL]  = "Illegal instruction";
105: #endif
106: #if !defined(PETSC_MISSING_SIGINT)
107:   /*  SIGNAME[SIGINT]  = "Interrupt"; */
108: #endif
109: #if !defined(PETSC_MISSING_SIGKILL)
110:   SIGNAME[SIGKILL] = "Kill";
111: #endif
112: #if !defined(PETSC_MISSING_SIGPIPE)
113:   SIGNAME[SIGPIPE] = "Broken Pipe";
114: #endif
115: #if !defined(PETSC_MISSING_SIGQUIT)
116:   SIGNAME[SIGQUIT] = "Quit";
117: #endif
118: #if !defined(PETSC_MISSING_SIGSEGV)
119:   SIGNAME[SIGSEGV] = "SEGV:\nPETSC ERROR: Segmentation Violation, probably memory access out of range";
120: #endif
121: #if !defined(PETSC_MISSING_SIGSTOP)
122:   SIGNAME[SIGSTOP] = "STOP";
123: #endif
124: #if !defined(PETSC_MISSING_SIGSYS)
125:   SIGNAME[SIGSYS]  = "SYS";
126: #endif
127: #if !defined(PETSC_MISSING_SIGTERM)
128:   SIGNAME[SIGTERM] = "Terminate";
129: #endif
130: #if !defined(PETSC_MISSING_SIGTRAP)
131:   SIGNAME[SIGTRAP] = "TRAP";
132: #endif
133: #if !defined(PETSC_MISSING_SIGTSTP)
134:   SIGNAME[SIGTSTP] = "TSTP";
135: #endif
136: #if !defined(PETSC_MISSING_SIGURG)
137:   SIGNAME[SIGURG]  = "URG";
138: #endif
139: #if !defined(PETSC_MISSING_SIGUSR1)
140:   SIGNAME[SIGUSR1] = "User 1";
141: #endif
142: #if !defined(PETSC_MISSING_SIGUSR2)
143:   SIGNAME[SIGUSR2] = "User 2";
144: #endif

146:   signal(sig,SIG_DFL);
147:   if (sig >= 0 && sig <= 20) {
148:     sprintf(buf,"Caught signal number %d %s\n",sig,SIGNAME[sig]);
149:   } else {
150:     PetscStrcpy(buf,"Caught signal\n");
151:   }
152:   PetscStrcat(buf,"PETSC ERROR: Try option -start_in_debugger or ");
153:   PetscStrcat(buf,"-on_error_attach_debugger ");
154:   PetscStrcat(buf,"to\nPETSC ERROR: determine where problem occurs\n");
155: #if defined(PETSC_USE_STACK)
156:   if (!PetscStackActive) {
157:     PetscStrcat(buf,"PETSC ERROR: or try option -log_stack\n");
158:   } else {
159:     PetscStackPop;  /* remove stack frames for error handlers */
160:     PetscStackPop;
161:     PetscStrcat(buf,"PETSC ERROR: likely location of problem given above in stack\n");
162:     (*PetscErrorPrintf)("--------------- Stack Frames ---------------\n");
163:     PetscStackView(PETSC_VIEWER_STDOUT_WORLD);
164:     (*PetscErrorPrintf)("--------------------------------------------\n");
165:   }
166: #endif
167: #if !defined(PETSC_USE_BOPT_g)
168:   PetscStrcat(buf,"PETSC ERROR: compile, link, and run with BOPT=g or g_c++ or g_complex\n");
169:   PetscStrcat(buf,"PETSC ERROR: to get more information on the crash.\n");
170: #endif
171:    PetscError(0,"User provided function","Unknown file","Unknown directory",PETSC_ERR_SIG,1,buf);
172:   MPI_Abort(PETSC_COMM_WORLD,ierr);
173:   return(0);
174: }

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

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

186:    Not Collective

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

192:   Level: developer

194:    Concepts: signal handler^setting

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

203:   if (!SignalSet && routine) {
204:     /* Do not catch ABRT, CHLD, KILL */
205: #if !defined(PETSC_MISSING_SIGALRM)
206:     /* signal(SIGALRM, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */
207: #endif
208: #if !defined(PETSC_MISSING_SIGBUS)
209:     signal(SIGBUS, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
210: #endif
211: #if !defined(PETSC_MISSING_SIGCONT)
212:     signal(SIGCONT, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
213: #endif
214: #if !defined(PETSC_MISSING_SIGFPE)
215:     signal(SIGFPE,  PETSC_SIGNAL_CAST PetscSignalHandler_Private);
216: #endif
217: #if !defined(PETSC_MISSING_SIGHUP)
218:     signal(SIGHUP, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
219: #endif
220: #if !defined(PETSC_MISSING_SIGILL)
221:     signal(SIGILL,  PETSC_SIGNAL_CAST PetscSignalHandler_Private);
222: #endif
223: #if !defined(PETSC_MISSING_SIGINT)
224:     /* signal(SIGINT, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */
225: #endif
226: #if !defined(PETSC_MISSING_SIGPIPE)
227:     signal(SIGPIPE, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
228: #endif
229: #if !defined(PETSC_MISSING_SIGQUIT)
230:     signal(SIGQUIT, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
231: #endif
232: #if !defined(PETSC_MISSING_SIGSEGV)
233:     signal(SIGSEGV, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
234: #endif
235: #if !defined(PETSC_MISSING_SIGSTOP)
236:     signal(SIGSTOP, 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_SIGSTOP)
293:     signal(SIGSTOP, 0);
294: #endif
295: #if !defined(PETSC_MISSING_SIGSYS)
296:     signal(SIGSYS,  0);
297: #endif
298: #if !defined(PETSC_MISSING_SIGTERM)
299:     signal(SIGTERM, 0);
300: #endif
301: #if !defined(PETSC_MISSING_SIGTRAP)
302:     signal(SIGTRAP, 0);
303: #endif
304: #if !defined(PETSC_MISSING_SIGTSTP)
305:     signal(SIGTSTP, 0);
306: #endif
307: #if !defined(PETSC_MISSING_SIGURG)
308:     signal(SIGURG,  0);
309: #endif
310: #if !defined(PETSC_MISSING_SIGUSR1)
311:     /*    signal(SIGUSR1, 0); */
312: #endif
313: #if !defined(PETSC_MISSING_SIGUSR2)
314:     /* signal(SIGUSR2, 0); */
315: #endif
316:     SignalSet = PETSC_FALSE;
317:   }
318:   PetscNew(struct SH,&newsh);
319:   if (sh) {newsh->previous = sh;}
320:   else {newsh->previous = 0;}
321:   newsh->handler = routine;
322:   newsh->ctx     = ctx;
323:   sh             = newsh;
324:   return(0);
325: }

327: /* NO ERROR CODES RETURNED BY THIS FUNCTION */
330: int PetscPopSignalHandler(void)
331: {
332:   struct SH *tmp;

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