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 petsc.h
7: #include <signal.h>
8: #include petscsys.h
9: #include "petscfix.h"
11: static PetscCookie SIGNAL_COOKIE = 0;
13: struct SH {
14: PetscCookie cookie;
15: PetscErrorCode (*handler)(int,void *);
16: void *ctx;
17: struct SH* previous;
18: };
19: static struct SH* sh = 0;
20: static PetscTruth SignalSet = PETSC_FALSE;
27: /*
28: PetscSignalHandler_Private - This is the signal handler called by the system. This calls
29: any signal handler set by PETSc or the application code.
30:
31: Input Parameters: (depends on system)
32: . sig - integer code indicating the type of signal
33: . code - ??
34: . sigcontext - ??
35: . addr - ??
41: */
42: #if defined(PETSC_HAVE_4ARG_SIGNAL_HANDLER)
43: static void PetscSignalHandler_Private(int sig,int code,struct sigcontext * scp,char *addr)
44: #else
45: static void PetscSignalHandler_Private(int sig)
46: #endif
47: {
51: if (!sh || !sh->handler) {
52: PetscDefaultSignalHandler(sig,(void*)0);
53: } else{
54: if (sh->cookie != SIGNAL_COOKIE) SETERRABORT(PETSC_COMM_WORLD,PETSC_ERR_COR,"Signal object has been corrupted");
55: (*sh->handler)(sig,sh->ctx);
56: }
57: if (ierr) MPI_Abort(PETSC_COMM_WORLD,0);
58: }
63: /*@
64: PetscDefaultSignalHandler - Default signal handler.
66: Not Collective
68: Level: advanced
70: Input Parameters:
71: + sig - signal value
72: - ptr - unused pointer
74: Concepts: signal handler^default
76: @*/
77: PetscErrorCode PetscDefaultSignalHandler(int sig,void *ptr)
78: {
80: const char *SIGNAME[64];
83: SIGNAME[0] = "Unknown signal";
84: #if !defined(PETSC_MISSING_SIGABRT)
85: SIGNAME[SIGABRT] = "Abort";
86: #endif
87: #if !defined(PETSC_MISSING_SIGALRM)
88: SIGNAME[SIGALRM] = "Alarm";
89: #endif
90: #if !defined(PETSC_MISSING_SIGBUS)
91: SIGNAME[SIGBUS] = "BUS: Bus Error, possibly illegal memory access";
92: #endif
93: #if !defined(PETSC_MISSING_SIGCHLD)
94: SIGNAME[SIGCHLD] = "CHLD";
95: #endif
96: #if !defined(PETSC_MISSING_SIGCONT)
97: SIGNAME[SIGCONT] = "CONT";
98: #endif
99: #if !defined(PETSC_MISSING_SIGFPE)
100: SIGNAME[SIGFPE] = "FPE: Floating Point Exception,probably divide by zero";
101: #endif
102: #if !defined(PETSC_MISSING_SIGHUP)
103: SIGNAME[SIGHUP] = "Hang up: Some other process (or the batch system) has told this process to end";
104: #endif
105: #if !defined(PETSC_MISSING_SIGILL)
106: SIGNAME[SIGILL] = "Illegal instruction: Likely due to memory corruption";
107: #endif
108: #if !defined(PETSC_MISSING_SIGINT)
109: SIGNAME[SIGINT] = "Interrupt";
110: #endif
111: #if !defined(PETSC_MISSING_SIGKILL)
112: SIGNAME[SIGKILL] = "Kill: Some other process (or the batch system) has told this process to end";
113: #endif
114: #if !defined(PETSC_MISSING_SIGPIPE)
115: SIGNAME[SIGPIPE] = "Broken Pipe: Likely while reading or writing to a socket";
116: #endif
117: #if !defined(PETSC_MISSING_SIGQUIT)
118: SIGNAME[SIGQUIT] = "Quit: Some other process (or the batch system) has told this process to end";
119: #endif
120: #if !defined(PETSC_MISSING_SIGSEGV)
121: SIGNAME[SIGSEGV] = "SEGV: Segmentation Violation, probably memory access out of range";
122: #endif
123: #if !defined(PETSC_MISSING_SIGSYS)
124: SIGNAME[SIGSYS] = "SYS";
125: #endif
126: #if !defined(PETSC_MISSING_SIGTERM)
127: SIGNAME[SIGTERM] = "Terminate: Somet process (or the batch system) has told this process to end";
128: #endif
129: #if !defined(PETSC_MISSING_SIGTRAP)
130: SIGNAME[SIGTRAP] = "TRAP";
131: #endif
132: #if !defined(PETSC_MISSING_SIGTSTP)
133: SIGNAME[SIGTSTP] = "TSTP";
134: #endif
135: #if !defined(PETSC_MISSING_SIGURG)
136: SIGNAME[SIGURG] = "URG";
137: #endif
138: #if !defined(PETSC_MISSING_SIGUSR1)
139: SIGNAME[SIGUSR1] = "User 1";
140: #endif
141: #if !defined(PETSC_MISSING_SIGUSR2)
142: SIGNAME[SIGUSR2] = "User 2";
143: #endif
145: signal(sig,SIG_DFL);
146: (*PetscErrorPrintf)("------------------------------------------------------------------------\n");
147: if (sig >= 0 && sig <= 20) {
148: (*PetscErrorPrintf)("Caught signal number %d %s\n",sig,SIGNAME[sig]);
149: } else {
150: (*PetscErrorPrintf)("Caught signal\n");
151: }
152: (*PetscErrorPrintf)("Try option -start_in_debugger or -on_error_attach_debugger\n");
153: (*PetscErrorPrintf)("or see http://www.mcs.anl.gov/petsc/petsc-as/documentation/troubleshooting.html#Signal");
154: (*PetscErrorPrintf)("or try http://valgrind.org on linux or man libgmalloc on Apple to find memory corruption errors\n");
155: #if defined(PETSC_USE_DEBUG)
156: if (!PetscStackActive) {
157: (*PetscErrorPrintf)(" or try option -log_stack\n");
158: } else {
159: PetscStackPop; /* remove stack frames for error handlers */
160: PetscStackPop;
161: (*PetscErrorPrintf)("likely location of problem given in stack below\n");
162: (*PetscErrorPrintf)("--------------------- Stack Frames ------------------------------------\n");
163: PetscStackView(PETSC_VIEWER_STDOUT_SELF);
164: }
165: #endif
166: #if !defined(PETSC_USE_DEBUG)
167: (*PetscErrorPrintf)("configure using --with-debugging=yes, recompile, link, and run \n");
168: (*PetscErrorPrintf)("to get more information on the crash.\n");
169: #endif
170: PetscError(0,"User provided function"," unknown file","unknown directory",PETSC_ERR_SIG,1,PETSC_NULL);
171: MPI_Abort(PETSC_COMM_WORLD,(int)ierr);
172: return(0);
173: }
175: #if !defined(PETSC_SIGNAL_CAST)
176: #define PETSC_SIGNAL_CAST
177: #endif
181: /*@C
182: PetscPushSignalHandler - Catches the usual fatal errors and
183: calls a user-provided routine.
185: Not Collective
187: Input Parameter:
188: + routine - routine to call when a signal is received
189: - ctx - optional context needed by the routine
191: Level: developer
193: Concepts: signal handler^setting
195: .seealso: PetscPopSignalHandler(), PetscDefaultSignalHandler()
197: @*/
198: PetscErrorCode PetscPushSignalHandler(PetscErrorCode (*routine)(int,void*),void* ctx)
199: {
200: struct SH *newsh;
204: if (!SIGNAL_COOKIE) {
205: /* PetscLogClassRegister(&SIGNAL_COOKIE,"Signal"); */
206: SIGNAL_COOKIE = 19;
207: }
208: if (!SignalSet && routine) {
209: /* Do not catch ABRT, CHLD, KILL */
210: #if !defined(PETSC_MISSING_SIGALRM)
211: /* signal(SIGALRM, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */
212: #endif
213: #if !defined(PETSC_MISSING_SIGBUS)
214: signal(SIGBUS, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
215: #endif
216: #if !defined(PETSC_MISSING_SIGCONT)
217: /*signal(SIGCONT, PETSC_SIGNAL_CAST PetscSignalHandler_Private);*/
218: #endif
219: #if !defined(PETSC_MISSING_SIGFPE)
220: signal(SIGFPE, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
221: #endif
222: #if !defined(PETSC_MISSING_SIGHUP)
223: signal(SIGHUP, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
224: #endif
225: #if !defined(PETSC_MISSING_SIGILL)
226: signal(SIGILL, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
227: #endif
228: #if !defined(PETSC_MISSING_SIGINT)
229: /* signal(SIGINT, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */
230: #endif
231: #if !defined(PETSC_MISSING_SIGPIPE)
232: signal(SIGPIPE, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
233: #endif
234: #if !defined(PETSC_MISSING_SIGQUIT)
235: signal(SIGQUIT, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
236: #endif
237: #if !defined(PETSC_MISSING_SIGSEGV)
238: signal(SIGSEGV, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
239: #endif
240: #if !defined(PETSC_MISSING_SIGSYS)
241: signal(SIGSYS, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
242: #endif
243: #if !defined(PETSC_MISSING_SIGTERM)
244: signal(SIGTERM, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
245: #endif
246: #if !defined(PETSC_MISSING_SIGTRAP)
247: signal(SIGTRAP, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
248: #endif
249: #if !defined(PETSC_MISSING_SIGTSTP)
250: /* signal(SIGTSTP, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */
251: #endif
252: #if !defined(PETSC_MISSING_SIGURG)
253: signal(SIGURG, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
254: #endif
255: #if !defined(PETSC_MISSING_SIGUSR1)
256: /* signal(SIGUSR1, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */
257: #endif
258: #if !defined(PETSC_MISSING_SIGUSR2)
259: /* signal(SIGUSR2, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */
260: #endif
261: SignalSet = PETSC_TRUE;
262: }
263: if (!routine) {
264: #if !defined(PETSC_MISSING_SIGALRM)
265: /* signal(SIGALRM, 0); */
266: #endif
267: #if !defined(PETSC_MISSING_SIGBUS)
268: signal(SIGBUS, 0);
269: #endif
270: #if !defined(PETSC_MISSING_SIGCONT)
271: /* signal(SIGCONT, 0); */
272: #endif
273: #if !defined(PETSC_MISSING_SIGFPE)
274: signal(SIGFPE, 0);
275: #endif
276: #if !defined(PETSC_MISSING_SIGHUP)
277: signal(SIGHUP, 0);
278: #endif
279: #if !defined(PETSC_MISSING_SIGILL)
280: signal(SIGILL, 0);
281: #endif
282: #if !defined(PETSC_MISSING_SIGINT)
283: /* signal(SIGINT, 0); */
284: #endif
285: #if !defined(PETSC_MISSING_SIGPIPE)
286: signal(SIGPIPE, 0);
287: #endif
288: #if !defined(PETSC_MISSING_SIGQUIT)
289: signal(SIGQUIT, 0);
290: #endif
291: #if !defined(PETSC_MISSING_SIGSEGV)
292: signal(SIGSEGV, 0);
293: #endif
294: #if !defined(PETSC_MISSING_SIGSYS)
295: signal(SIGSYS, 0);
296: #endif
297: #if !defined(PETSC_MISSING_SIGTERM)
298: signal(SIGTERM, 0);
299: #endif
300: #if !defined(PETSC_MISSING_SIGTRAP)
301: signal(SIGTRAP, 0);
302: #endif
303: #if !defined(PETSC_MISSING_SIGTSTP)
304: /* signal(SIGTSTP, 0); */
305: #endif
306: #if !defined(PETSC_MISSING_SIGURG)
307: signal(SIGURG, 0);
308: #endif
309: #if !defined(PETSC_MISSING_SIGUSR1)
310: /* signal(SIGUSR1, 0); */
311: #endif
312: #if !defined(PETSC_MISSING_SIGUSR2)
313: /* signal(SIGUSR2, 0); */
314: #endif
315: SignalSet = PETSC_FALSE;
316: }
317: PetscNew(struct SH,&newsh);
318: if (sh) {
319: if (sh->cookie != SIGNAL_COOKIE) SETERRQ(PETSC_ERR_COR,"Signal object has been corrupted");
320: newsh->previous = sh;
321: }
322: else {newsh->previous = 0;}
323: newsh->handler = routine;
324: newsh->ctx = ctx;
325: newsh->cookie = SIGNAL_COOKIE;
326: sh = newsh;
327: return(0);
328: }
332: /*@
333: PetscPopSignalHandler - Removes the most last signal handler that was pushed.
334: If no signal handlers are left on the stack it will remove the PETSc signal handler.
335: (That is PETSc will no longer catch signals).
337: Not Collective
339: Level: developer
341: Concepts: signal handler^setting
343: .seealso: PetscPushSignalHandler()
345: @*/
346: PetscErrorCode PetscPopSignalHandler(void)
347: {
348: struct SH *tmp;
351: if (!sh) return(0);
352: if (sh->cookie != SIGNAL_COOKIE) SETERRQ(PETSC_ERR_COR,"Signal object has been corrupted");
354: tmp = sh;
355: sh = sh->previous;
356: PetscFreeVoid(tmp);
357: if (!sh || !sh->handler) {
358: #if !defined(PETSC_MISSING_SIGALRM)
359: /* signal(SIGALRM, 0); */
360: #endif
361: #if !defined(PETSC_MISSING_SIGBUS)
362: signal(SIGBUS, 0);
363: #endif
364: #if !defined(PETSC_MISSING_SIGCONT)
365: /* signal(SIGCONT, 0); */
366: #endif
367: #if !defined(PETSC_MISSING_SIGFPE)
368: signal(SIGFPE, 0);
369: #endif
370: #if !defined(PETSC_MISSING_SIGHUP)
371: signal(SIGHUP, 0);
372: #endif
373: #if !defined(PETSC_MISSING_SIGILL)
374: signal(SIGILL, 0);
375: #endif
376: #if !defined(PETSC_MISSING_SIGINT)
377: /* signal(SIGINT, 0); */
378: #endif
379: #if !defined(PETSC_MISSING_SIGPIPE)
380: signal(SIGPIPE, 0);
381: #endif
382: #if !defined(PETSC_MISSING_SIGQUIT)
383: signal(SIGQUIT, 0);
384: #endif
385: #if !defined(PETSC_MISSING_SIGSEGV)
386: signal(SIGSEGV, 0);
387: #endif
388: #if !defined(PETSC_MISSING_SIGSYS)
389: signal(SIGSYS, 0);
390: #endif
391: #if !defined(PETSC_MISSING_SIGTERM)
392: signal(SIGTERM, 0);
393: #endif
394: #if !defined(PETSC_MISSING_SIGTRAP)
395: signal(SIGTRAP, 0);
396: #endif
397: #if !defined(PETSC_MISSING_SIGTSTP)
398: /* signal(SIGTSTP, 0); */
399: #endif
400: #if !defined(PETSC_MISSING_SIGURG)
401: signal(SIGURG, 0);
402: #endif
403: #if !defined(PETSC_MISSING_SIGUSR1)
404: /* signal(SIGUSR1, 0); */
405: #endif
406: #if !defined(PETSC_MISSING_SIGUSR2)
407: /* signal(SIGUSR2, 0); */
408: #endif
409: SignalSet = PETSC_FALSE;
410: } else {
411: SignalSet = PETSC_TRUE;
412: }
413: return(0);
414: }