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 PETSC_DLLEXPORT 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: if (sig >= 0 && sig <= 20) {
147: (*PetscErrorPrintf)("Caught signal number %d %s\n",sig,SIGNAME[sig]);
148: } else {
149: (*PetscErrorPrintf)("Caught signal\n");
150: }
151: (*PetscErrorPrintf)("Try option -start_in_debugger or -on_error_attach_debugger\n");
152: (*PetscErrorPrintf)("or try http://valgrind.org on linux to find memory corruption errors\n");
153: #if defined(PETSC_USE_DEBUG)
154: if (!PetscStackActive) {
155: (*PetscErrorPrintf)(" or try option -log_stack\n");
156: } else {
157: PetscStackPop; /* remove stack frames for error handlers */
158: PetscStackPop;
159: (*PetscErrorPrintf)("likely location of problem given in stack below\n");
160: (*PetscErrorPrintf)("--------------- Stack Frames ---------------\n");
161: PetscStackView(PETSC_VIEWER_STDOUT_SELF);
162: (*PetscErrorPrintf)("--------------------------------------------\n");
163: }
164: #endif
165: #if !defined(PETSC_USE_DEBUG)
166: (*PetscErrorPrintf)("configure using --with-debugging=yes, recompile, link, and run \n");
167: (*PetscErrorPrintf)("to get more information on the crash.\n");
168: #endif
169: PetscError(0,"User provided function"," unknown file","unknown directory",PETSC_ERR_SIG,1," ");
170: MPI_Abort(PETSC_COMM_WORLD,(int)ierr);
171: return(0);
172: }
174: #if !defined(PETSC_SIGNAL_CAST)
175: #define PETSC_SIGNAL_CAST
176: #endif
180: /*@C
181: PetscPushSignalHandler - Catches the usual fatal errors and
182: calls a user-provided routine.
184: Not Collective
186: Input Parameter:
187: + routine - routine to call when a signal is received
188: - ctx - optional context needed by the routine
190: Level: developer
192: Concepts: signal handler^setting
194: .seealso: PetscPopSignalHandler(), PetscDefaultSignalHandler()
196: @*/
197: PetscErrorCode PETSC_DLLEXPORT PetscPushSignalHandler(PetscErrorCode (*routine)(int,void*),void* ctx)
198: {
199: struct SH *newsh;
203: if (!SIGNAL_COOKIE) {
204: /* PetscLogClassRegister(&SIGNAL_COOKIE,"Signal"); */
205: SIGNAL_COOKIE = 19;
206: }
207: if (!SignalSet && routine) {
208: /* Do not catch ABRT, CHLD, KILL */
209: #if !defined(PETSC_MISSING_SIGALRM)
210: /* signal(SIGALRM, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */
211: #endif
212: #if !defined(PETSC_MISSING_SIGBUS)
213: signal(SIGBUS, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
214: #endif
215: #if !defined(PETSC_MISSING_SIGCONT)
216: /*signal(SIGCONT, PETSC_SIGNAL_CAST PetscSignalHandler_Private);*/
217: #endif
218: #if !defined(PETSC_MISSING_SIGFPE)
219: signal(SIGFPE, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
220: #endif
221: #if !defined(PETSC_MISSING_SIGHUP)
222: signal(SIGHUP, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
223: #endif
224: #if !defined(PETSC_MISSING_SIGILL)
225: signal(SIGILL, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
226: #endif
227: #if !defined(PETSC_MISSING_SIGINT)
228: /* signal(SIGINT, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */
229: #endif
230: #if !defined(PETSC_MISSING_SIGPIPE)
231: signal(SIGPIPE, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
232: #endif
233: #if !defined(PETSC_MISSING_SIGQUIT)
234: signal(SIGQUIT, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
235: #endif
236: #if !defined(PETSC_MISSING_SIGSEGV)
237: signal(SIGSEGV, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
238: #endif
239: #if !defined(PETSC_MISSING_SIGSYS)
240: signal(SIGSYS, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
241: #endif
242: #if !defined(PETSC_MISSING_SIGTERM)
243: signal(SIGTERM, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
244: #endif
245: #if !defined(PETSC_MISSING_SIGTRAP)
246: signal(SIGTRAP, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
247: #endif
248: #if !defined(PETSC_MISSING_SIGTSTP)
249: /* signal(SIGTSTP, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */
250: #endif
251: #if !defined(PETSC_MISSING_SIGURG)
252: signal(SIGURG, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
253: #endif
254: #if !defined(PETSC_MISSING_SIGUSR1)
255: /* signal(SIGUSR1, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */
256: #endif
257: #if !defined(PETSC_MISSING_SIGUSR2)
258: /* signal(SIGUSR2, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */
259: #endif
260: SignalSet = PETSC_TRUE;
261: }
262: if (!routine) {
263: #if !defined(PETSC_MISSING_SIGALRM)
264: /* signal(SIGALRM, 0); */
265: #endif
266: #if !defined(PETSC_MISSING_SIGBUS)
267: signal(SIGBUS, 0);
268: #endif
269: #if !defined(PETSC_MISSING_SIGCONT)
270: /* signal(SIGCONT, 0); */
271: #endif
272: #if !defined(PETSC_MISSING_SIGFPE)
273: signal(SIGFPE, 0);
274: #endif
275: #if !defined(PETSC_MISSING_SIGHUP)
276: signal(SIGHUP, 0);
277: #endif
278: #if !defined(PETSC_MISSING_SIGILL)
279: signal(SIGILL, 0);
280: #endif
281: #if !defined(PETSC_MISSING_SIGINT)
282: /* signal(SIGINT, 0); */
283: #endif
284: #if !defined(PETSC_MISSING_SIGPIPE)
285: signal(SIGPIPE, 0);
286: #endif
287: #if !defined(PETSC_MISSING_SIGQUIT)
288: signal(SIGQUIT, 0);
289: #endif
290: #if !defined(PETSC_MISSING_SIGSEGV)
291: signal(SIGSEGV, 0);
292: #endif
293: #if !defined(PETSC_MISSING_SIGSYS)
294: signal(SIGSYS, 0);
295: #endif
296: #if !defined(PETSC_MISSING_SIGTERM)
297: signal(SIGTERM, 0);
298: #endif
299: #if !defined(PETSC_MISSING_SIGTRAP)
300: signal(SIGTRAP, 0);
301: #endif
302: #if !defined(PETSC_MISSING_SIGTSTP)
303: /* signal(SIGTSTP, 0); */
304: #endif
305: #if !defined(PETSC_MISSING_SIGURG)
306: signal(SIGURG, 0);
307: #endif
308: #if !defined(PETSC_MISSING_SIGUSR1)
309: /* signal(SIGUSR1, 0); */
310: #endif
311: #if !defined(PETSC_MISSING_SIGUSR2)
312: /* signal(SIGUSR2, 0); */
313: #endif
314: SignalSet = PETSC_FALSE;
315: }
316: PetscNew(struct SH,&newsh);
317: if (sh) {
318: if (sh->cookie != SIGNAL_COOKIE) SETERRQ(PETSC_ERR_COR,"Signal object has been corrupted");
319: newsh->previous = sh;
320: }
321: else {newsh->previous = 0;}
322: newsh->handler = routine;
323: newsh->ctx = ctx;
324: newsh->cookie = SIGNAL_COOKIE;
325: sh = newsh;
326: return(0);
327: }
331: /*@
332: PetscPopSignalHandler - Removes the most last signal handler that was pushed.
333: If no signal handlers are left on the stack it will remove the PETSc signal handler.
334: (That is PETSc will no longer catch signals).
336: Not Collective
338: Level: developer
340: Concepts: signal handler^setting
342: .seealso: PetscPushSignalHandler()
344: @*/
345: PetscErrorCode PETSC_DLLEXPORT PetscPopSignalHandler(void)
346: {
347: struct SH *tmp;
350: if (!sh) return(0);
351: if (sh->cookie != SIGNAL_COOKIE) SETERRQ(PETSC_ERR_COR,"Signal object has been corrupted");
353: tmp = sh;
354: sh = sh->previous;
355: PetscFreeVoid(tmp);
356: if (!sh || !sh->handler) {
357: #if !defined(PETSC_MISSING_SIGALRM)
358: /* signal(SIGALRM, 0); */
359: #endif
360: #if !defined(PETSC_MISSING_SIGBUS)
361: signal(SIGBUS, 0);
362: #endif
363: #if !defined(PETSC_MISSING_SIGCONT)
364: /* signal(SIGCONT, 0); */
365: #endif
366: #if !defined(PETSC_MISSING_SIGFPE)
367: signal(SIGFPE, 0);
368: #endif
369: #if !defined(PETSC_MISSING_SIGHUP)
370: signal(SIGHUP, 0);
371: #endif
372: #if !defined(PETSC_MISSING_SIGILL)
373: signal(SIGILL, 0);
374: #endif
375: #if !defined(PETSC_MISSING_SIGINT)
376: /* signal(SIGINT, 0); */
377: #endif
378: #if !defined(PETSC_MISSING_SIGPIPE)
379: signal(SIGPIPE, 0);
380: #endif
381: #if !defined(PETSC_MISSING_SIGQUIT)
382: signal(SIGQUIT, 0);
383: #endif
384: #if !defined(PETSC_MISSING_SIGSEGV)
385: signal(SIGSEGV, 0);
386: #endif
387: #if !defined(PETSC_MISSING_SIGSYS)
388: signal(SIGSYS, 0);
389: #endif
390: #if !defined(PETSC_MISSING_SIGTERM)
391: signal(SIGTERM, 0);
392: #endif
393: #if !defined(PETSC_MISSING_SIGTRAP)
394: signal(SIGTRAP, 0);
395: #endif
396: #if !defined(PETSC_MISSING_SIGTSTP)
397: /* signal(SIGTSTP, 0); */
398: #endif
399: #if !defined(PETSC_MISSING_SIGURG)
400: signal(SIGURG, 0);
401: #endif
402: #if !defined(PETSC_MISSING_SIGUSR1)
403: /* signal(SIGUSR1, 0); */
404: #endif
405: #if !defined(PETSC_MISSING_SIGUSR2)
406: /* signal(SIGUSR2, 0); */
407: #endif
408: SignalSet = PETSC_FALSE;
409: } else {
410: SignalSet = PETSC_TRUE;
411: }
412: return(0);
413: }