Actual source code: signal.c
1: /*
2: Routines to handle signals the program will receive.
3: Usually this will call the error handlers.
4: */
5: #include <signal.h>
6: #include petsc.h
7: #include petscsys.h
8: #include "petscfix.h"
10: struct SH {
11: int cookie;
12: PetscErrorCode (*handler)(int,void *);
13: void *ctx;
14: struct SH* previous;
15: };
16: static struct SH* sh = 0;
17: static PetscTruth SignalSet = PETSC_FALSE;
24: /*
25: PetscSignalHandler_Private - This is the signal handler called by the system. This calls
26: any signal handler set by PETSc or the application code.
27:
28: Input Parameters: (depends on system)
29: . sig - integer code indicating the type of signal
30: . code - ??
31: . sigcontext - ??
32: . addr - ??
38: */
39: #if defined(PETSC_HAVE_4ARG_SIGNAL_HANDLER)
40: static void PetscSignalHandler_Private(int sig,int code,struct sigcontext * scp,char *addr)
41: #else
42: static void PetscSignalHandler_Private(int sig)
43: #endif
44: {
48: if (!sh || !sh->handler) {
49: PetscDefaultSignalHandler(sig,(void*)0);
50: } else{
51: (*sh->handler)(sig,sh->ctx);
52: }
53: if (ierr) MPI_Abort(PETSC_COMM_WORLD,0);
54: }
59: /*@
60: PetscDefaultSignalHandler - Default signal handler.
62: Not Collective
64: Level: advanced
66: Input Parameters:
67: + sig - signal value
68: - ptr - unused pointer
70: Concepts: signal handler^default
72: @*/
73: PetscErrorCode PetscDefaultSignalHandler(int sig,void *ptr)
74: {
76: const char *SIGNAME[64];
79: SIGNAME[0] = "Unknown signal";
80: #if !defined(PETSC_MISSING_SIGABRT)
81: SIGNAME[SIGABRT] = "Abort";
82: #endif
83: #if !defined(PETSC_MISSING_SIGALRM)
84: /* SIGNAME[SIGALRM] = "Alarm"; */
85: #endif
86: #if !defined(PETSC_MISSING_SIGBUS)
87: SIGNAME[SIGBUS] = "BUS: Bus Error, possibly illegal memory access";
88: #endif
89: #if !defined(PETSC_MISSING_SIGCHLD)
90: SIGNAME[SIGCHLD] = "CHLD";
91: #endif
92: #if !defined(PETSC_MISSING_SIGCONT)
93: SIGNAME[SIGCONT] = "CONT";
94: #endif
95: #if !defined(PETSC_MISSING_SIGFPE)
96: SIGNAME[SIGFPE] = "FPE: Floating Point Exception,probably divide by zero";
97: #endif
98: #if !defined(PETSC_MISSING_SIGHUP)
99: SIGNAME[SIGHUP] = "Hang up";
100: #endif
101: #if !defined(PETSC_MISSING_SIGILL)
102: SIGNAME[SIGILL] = "Illegal instruction";
103: #endif
104: #if !defined(PETSC_MISSING_SIGINT)
105: /* SIGNAME[SIGINT] = "Interrupt"; */
106: #endif
107: #if !defined(PETSC_MISSING_SIGKILL)
108: SIGNAME[SIGKILL] = "Kill";
109: #endif
110: #if !defined(PETSC_MISSING_SIGPIPE)
111: SIGNAME[SIGPIPE] = "Broken Pipe";
112: #endif
113: #if !defined(PETSC_MISSING_SIGQUIT)
114: SIGNAME[SIGQUIT] = "Quit";
115: #endif
116: #if !defined(PETSC_MISSING_SIGSEGV)
117: SIGNAME[SIGSEGV] = "SEGV: Segmentation Violation, probably memory access out of range";
118: #endif
119: #if !defined(PETSC_MISSING_SIGSYS)
120: SIGNAME[SIGSYS] = "SYS";
121: #endif
122: #if !defined(PETSC_MISSING_SIGTERM)
123: SIGNAME[SIGTERM] = "Terminate";
124: #endif
125: #if !defined(PETSC_MISSING_SIGTRAP)
126: SIGNAME[SIGTRAP] = "TRAP";
127: #endif
128: #if !defined(PETSC_MISSING_SIGTSTP)
129: SIGNAME[SIGTSTP] = "TSTP";
130: #endif
131: #if !defined(PETSC_MISSING_SIGURG)
132: SIGNAME[SIGURG] = "URG";
133: #endif
134: #if !defined(PETSC_MISSING_SIGUSR1)
135: SIGNAME[SIGUSR1] = "User 1";
136: #endif
137: #if !defined(PETSC_MISSING_SIGUSR2)
138: SIGNAME[SIGUSR2] = "User 2";
139: #endif
141: signal(sig,SIG_DFL);
142: if (sig >= 0 && sig <= 20) {
143: (*PetscErrorPrintf)("Caught signal number %d %s\n",sig,SIGNAME[sig]);
144: } else {
145: (*PetscErrorPrintf)("Caught signal\n");
146: }
147: (*PetscErrorPrintf)("Try option -start_in_debugger or -on_error_attach_debugger\n");
148: #if defined(PETSC_USE_STACK)
149: if (!PetscStackActive) {
150: (*PetscErrorPrintf)(" or try option -log_stack\n");
151: } else {
152: PetscStackPop; /* remove stack frames for error handlers */
153: PetscStackPop;
154: (*PetscErrorPrintf)("likely location of problem given in stack below\n");
155: (*PetscErrorPrintf)("--------------- Stack Frames ---------------\n");
156: PetscStackView(PETSC_VIEWER_STDOUT_SELF);
157: (*PetscErrorPrintf)("--------------------------------------------\n");
158: }
159: #endif
160: #if !defined(PETSC_USE_BOPT_g)
161: (*PetscErrorPrintf)("compile, link, and run with BOPT=g or g_c++ or g_complex\n");
162: (*PetscErrorPrintf)("to get more information on the crash.\n");
163: #endif
164: PetscError(0,"User provided function"," unknown file","unknown directory",PETSC_ERR_SIG,1," ");
165: MPI_Abort(PETSC_COMM_WORLD,(int)ierr);
166: return(0);
167: }
169: #if !defined(PETSC_SIGNAL_CAST)
170: #define PETSC_SIGNAL_CAST
171: #endif
175: /*@C
176: PetscPushSignalHandler - Catches the usual fatal errors and
177: calls a user-provided routine.
179: Not Collective
181: Input Parameter:
182: + routine - routine to call when a signal is received
183: - ctx - optional context needed by the routine
185: Level: developer
187: Concepts: signal handler^setting
189: .seealso: PetscPopSignalHandler(), PetscDefaultSignalHandler()
191: @*/
192: PetscErrorCode PetscPushSignalHandler(PetscErrorCode (*routine)(int,void*),void* ctx)
193: {
194: struct SH *newsh;
198: if (!SignalSet && routine) {
199: /* Do not catch ABRT, CHLD, KILL */
200: #if !defined(PETSC_MISSING_SIGALRM)
201: /* signal(SIGALRM, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */
202: #endif
203: #if !defined(PETSC_MISSING_SIGBUS)
204: signal(SIGBUS, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
205: #endif
206: #if !defined(PETSC_MISSING_SIGCONT)
207: /*signal(SIGCONT, PETSC_SIGNAL_CAST PetscSignalHandler_Private);*/
208: #endif
209: #if !defined(PETSC_MISSING_SIGFPE)
210: signal(SIGFPE, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
211: #endif
212: #if !defined(PETSC_MISSING_SIGHUP)
213: signal(SIGHUP, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
214: #endif
215: #if !defined(PETSC_MISSING_SIGILL)
216: signal(SIGILL, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
217: #endif
218: #if !defined(PETSC_MISSING_SIGINT)
219: /* signal(SIGINT, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */
220: #endif
221: #if !defined(PETSC_MISSING_SIGPIPE)
222: signal(SIGPIPE, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
223: #endif
224: #if !defined(PETSC_MISSING_SIGQUIT)
225: signal(SIGQUIT, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
226: #endif
227: #if !defined(PETSC_MISSING_SIGSEGV)
228: signal(SIGSEGV, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
229: #endif
230: #if !defined(PETSC_MISSING_SIGSYS)
231: signal(SIGSYS, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
232: #endif
233: #if !defined(PETSC_MISSING_SIGTERM)
234: signal(SIGTERM, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
235: #endif
236: #if !defined(PETSC_MISSING_SIGTRAP)
237: signal(SIGTRAP, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
238: #endif
239: #if !defined(PETSC_MISSING_SIGTSTP)
240: /* signal(SIGTSTP, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */
241: #endif
242: #if !defined(PETSC_MISSING_SIGURG)
243: signal(SIGURG, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
244: #endif
245: #if !defined(PETSC_MISSING_SIGUSR1)
246: /* signal(SIGUSR1, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */
247: #endif
248: #if !defined(PETSC_MISSING_SIGUSR2)
249: /* signal(SIGUSR2, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */
250: #endif
251: SignalSet = PETSC_TRUE;
252: }
253: if (!routine) {
254: #if !defined(PETSC_MISSING_SIGALRM)
255: /* signal(SIGALRM, 0); */
256: #endif
257: #if !defined(PETSC_MISSING_SIGBUS)
258: signal(SIGBUS, 0);
259: #endif
260: #if !defined(PETSC_MISSING_SIGCONT)
261: /* signal(SIGCONT, 0); */
262: #endif
263: #if !defined(PETSC_MISSING_SIGFPE)
264: signal(SIGFPE, 0);
265: #endif
266: #if !defined(PETSC_MISSING_SIGHUP)
267: signal(SIGHUP, 0);
268: #endif
269: #if !defined(PETSC_MISSING_SIGILL)
270: signal(SIGILL, 0);
271: #endif
272: #if !defined(PETSC_MISSING_SIGINT)
273: /* signal(SIGINT, 0); */
274: #endif
275: #if !defined(PETSC_MISSING_SIGPIPE)
276: signal(SIGPIPE, 0);
277: #endif
278: #if !defined(PETSC_MISSING_SIGQUIT)
279: signal(SIGQUIT, 0);
280: #endif
281: #if !defined(PETSC_MISSING_SIGSEGV)
282: signal(SIGSEGV, 0);
283: #endif
284: #if !defined(PETSC_MISSING_SIGSYS)
285: signal(SIGSYS, 0);
286: #endif
287: #if !defined(PETSC_MISSING_SIGTERM)
288: signal(SIGTERM, 0);
289: #endif
290: #if !defined(PETSC_MISSING_SIGTRAP)
291: signal(SIGTRAP, 0);
292: #endif
293: #if !defined(PETSC_MISSING_SIGTSTP)
294: /* signal(SIGTSTP, 0); */
295: #endif
296: #if !defined(PETSC_MISSING_SIGURG)
297: signal(SIGURG, 0);
298: #endif
299: #if !defined(PETSC_MISSING_SIGUSR1)
300: /* signal(SIGUSR1, 0); */
301: #endif
302: #if !defined(PETSC_MISSING_SIGUSR2)
303: /* signal(SIGUSR2, 0); */
304: #endif
305: SignalSet = PETSC_FALSE;
306: }
307: PetscNew(struct SH,&newsh);
308: if (sh) {newsh->previous = sh;}
309: else {newsh->previous = 0;}
310: newsh->handler = routine;
311: newsh->ctx = ctx;
312: sh = newsh;
313: return(0);
314: }
318: /*@C
319: PetscPopSignalHandler - Removes the most last signal handler that was pushed.
320: If no signal handlers are left on the stack it will remove the PETSc signal handler.
321: (That is PETSc will no longer catch signals).
323: Not Collective
325: Level: developer
327: Note: NO ERROR CODES RETURNED BY THIS FUNCTION
329: Concepts: signal handler^setting
331: .seealso: PetscPushSignalHandler()
333: @*/
334: PetscErrorCode PetscPopSignalHandler(void)
335: {
336: struct SH *tmp;
339: if (!sh) return(0);
340: tmp = sh;
341: sh = sh->previous;
342: PetscFree(tmp);
343: if (!sh || !sh->handler) {
344: #if !defined(PETSC_MISSING_SIGALRM)
345: /* signal(SIGALRM, 0); */
346: #endif
347: #if !defined(PETSC_MISSING_SIGBUS)
348: signal(SIGBUS, 0);
349: #endif
350: #if !defined(PETSC_MISSING_SIGCONT)
351: /* signal(SIGCONT, 0); */
352: #endif
353: #if !defined(PETSC_MISSING_SIGFPE)
354: signal(SIGFPE, 0);
355: #endif
356: #if !defined(PETSC_MISSING_SIGHUP)
357: signal(SIGHUP, 0);
358: #endif
359: #if !defined(PETSC_MISSING_SIGILL)
360: signal(SIGILL, 0);
361: #endif
362: #if !defined(PETSC_MISSING_SIGINT)
363: /* signal(SIGINT, 0); */
364: #endif
365: #if !defined(PETSC_MISSING_SIGPIPE)
366: signal(SIGPIPE, 0);
367: #endif
368: #if !defined(PETSC_MISSING_SIGQUIT)
369: signal(SIGQUIT, 0);
370: #endif
371: #if !defined(PETSC_MISSING_SIGSEGV)
372: signal(SIGSEGV, 0);
373: #endif
374: #if !defined(PETSC_MISSING_SIGSYS)
375: signal(SIGSYS, 0);
376: #endif
377: #if !defined(PETSC_MISSING_SIGTERM)
378: signal(SIGTERM, 0);
379: #endif
380: #if !defined(PETSC_MISSING_SIGTRAP)
381: signal(SIGTRAP, 0);
382: #endif
383: #if !defined(PETSC_MISSING_SIGTSTP)
384: /* signal(SIGTSTP, 0); */
385: #endif
386: #if !defined(PETSC_MISSING_SIGURG)
387: signal(SIGURG, 0);
388: #endif
389: #if !defined(PETSC_MISSING_SIGUSR1)
390: /* signal(SIGUSR1, 0); */
391: #endif
392: #if !defined(PETSC_MISSING_SIGUSR2)
393: /* signal(SIGUSR2, 0); */
394: #endif
395: SignalSet = PETSC_FALSE;
396: } else {
397: SignalSet = PETSC_TRUE;
398: }
399: return(0);
400: }