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