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