Actual source code: signal.c
petsc-3.3-p7 2013-05-11
2: /*
3: Routines to handle signals the program will receive.
4: Usually this will call the error handlers.
5: */
6: #include <petscsys.h> /*I "petscsys.h" I*/
7: #include <signal.h>
9: static PetscClassId SIGNAL_CLASSID = 0;
11: struct SH {
12: PetscClassId classid;
13: PetscErrorCode (*handler)(int,void *);
14: void *ctx;
15: struct SH* previous;
16: };
17: static struct SH* sh = 0;
18: static PetscBool 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: if (sh->classid != SIGNAL_CLASSID) SETERRABORT(PETSC_COMM_WORLD,PETSC_ERR_COR,"Signal object has been corrupted");
53: (*sh->handler)(sig,sh->ctx);
54: }
55: if (ierr) MPI_Abort(PETSC_COMM_WORLD,0);
56: }
57: EXTERN_C_END
61: /*@
62: PetscDefaultSignalHandler - Default signal handler.
64: Not Collective
66: Level: advanced
68: Input Parameters:
69: + sig - signal value
70: - ptr - unused pointer
72: Concepts: signal handler^default
74: @*/
75: PetscErrorCode PetscDefaultSignalHandler(int sig,void *ptr)
76: {
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: 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: Floating Point Exception,probably divide by zero";
99: #endif
100: #if !defined(PETSC_MISSING_SIGHUP)
101: SIGNAME[SIGHUP] = "Hang up: Some other process (or the batch system) has told this process to end";
102: #endif
103: #if !defined(PETSC_MISSING_SIGILL)
104: SIGNAME[SIGILL] = "Illegal instruction: Likely due to memory corruption";
105: #endif
106: #if !defined(PETSC_MISSING_SIGINT)
107: SIGNAME[SIGINT] = "Interrupt";
108: #endif
109: #if !defined(PETSC_MISSING_SIGKILL)
110: SIGNAME[SIGKILL] = "Kill: Some other process (or the batch system) has told this process to end";
111: #endif
112: #if !defined(PETSC_MISSING_SIGPIPE)
113: SIGNAME[SIGPIPE] = "Broken Pipe: Likely while reading or writing to a socket";
114: #endif
115: #if !defined(PETSC_MISSING_SIGQUIT)
116: SIGNAME[SIGQUIT] = "Quit: Some other process (or the batch system) has told this process to end";
117: #endif
118: #if !defined(PETSC_MISSING_SIGSEGV)
119: SIGNAME[SIGSEGV] = "SEGV: Segmentation Violation, probably memory access out of range";
120: #endif
121: #if !defined(PETSC_MISSING_SIGSYS)
122: SIGNAME[SIGSYS] = "SYS";
123: #endif
124: #if !defined(PETSC_MISSING_SIGTERM)
125: SIGNAME[SIGTERM] = "Terminate: Somet process (or the batch system) has told this process to end";
126: #endif
127: #if !defined(PETSC_MISSING_SIGTRAP)
128: SIGNAME[SIGTRAP] = "TRAP";
129: #endif
130: #if !defined(PETSC_MISSING_SIGTSTP)
131: SIGNAME[SIGTSTP] = "TSTP";
132: #endif
133: #if !defined(PETSC_MISSING_SIGURG)
134: SIGNAME[SIGURG] = "URG";
135: #endif
136: #if !defined(PETSC_MISSING_SIGUSR1)
137: SIGNAME[SIGUSR1] = "User 1";
138: #endif
139: #if !defined(PETSC_MISSING_SIGUSR2)
140: SIGNAME[SIGUSR2] = "User 2";
141: #endif
143: signal(sig,SIG_DFL);
144: (*PetscErrorPrintf)("------------------------------------------------------------------------\n");
145: if (sig >= 0 && sig <= 20) {
146: (*PetscErrorPrintf)("Caught signal number %d %s\n",sig,SIGNAME[sig]);
147: } else {
148: (*PetscErrorPrintf)("Caught signal\n");
149: }
150: (*PetscErrorPrintf)("Try option -start_in_debugger or -on_error_attach_debugger\n");
151: (*PetscErrorPrintf)("or see http://www.mcs.anl.gov/petsc/documentation/faq.html#valgrind");
152: (*PetscErrorPrintf)("or try http://valgrind.org on GNU/linux and Apple Mac OS X 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: }
163: #endif
164: #if !defined(PETSC_USE_DEBUG)
165: (*PetscErrorPrintf)("configure using --with-debugging=yes, recompile, link, and run \n");
166: (*PetscErrorPrintf)("to get more information on the crash.\n");
167: #endif
168: PetscError(PETSC_COMM_SELF,0,"User provided function"," unknown file","unknown directory",PETSC_ERR_SIG,PETSC_ERROR_INITIAL,PETSC_NULL);
169: MPI_Abort(PETSC_COMM_WORLD,(int)ierr);
170: return(0);
171: }
173: #if !defined(PETSC_SIGNAL_CAST)
174: #define PETSC_SIGNAL_CAST
175: #endif
179: /*@C
180: PetscPushSignalHandler - Catches the usual fatal errors and
181: calls a user-provided routine.
183: Not Collective
185: Input Parameter:
186: + routine - routine to call when a signal is received
187: - ctx - optional context needed by the routine
189: Level: developer
191: Concepts: signal handler^setting
193: .seealso: PetscPopSignalHandler(), PetscDefaultSignalHandler()
195: @*/
196: PetscErrorCode PetscPushSignalHandler(PetscErrorCode (*routine)(int,void*),void* ctx)
197: {
198: struct SH *newsh;
202: if (!SIGNAL_CLASSID) {
203: /* PetscClassIdRegister("Signal",&SIGNAL_CLASSID); */
204: SIGNAL_CLASSID = 19;
205: }
206: if (!SignalSet && routine) {
207: /* Do not catch ABRT, CHLD, KILL */
208: #if !defined(PETSC_MISSING_SIGALRM)
209: /* signal(SIGALRM, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */
210: #endif
211: #if !defined(PETSC_MISSING_SIGBUS)
212: signal(SIGBUS, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
213: #endif
214: #if !defined(PETSC_MISSING_SIGCONT)
215: /*signal(SIGCONT, PETSC_SIGNAL_CAST PetscSignalHandler_Private);*/
216: #endif
217: #if !defined(PETSC_MISSING_SIGFPE)
218: signal(SIGFPE, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
219: #endif
220: #if !defined(PETSC_MISSING_SIGHUP)
221: signal(SIGHUP, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
222: #endif
223: #if !defined(PETSC_MISSING_SIGILL)
224: signal(SIGILL, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
225: #endif
226: #if !defined(PETSC_MISSING_SIGINT)
227: /* signal(SIGINT, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */
228: #endif
229: #if !defined(PETSC_MISSING_SIGPIPE)
230: signal(SIGPIPE, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
231: #endif
232: #if !defined(PETSC_MISSING_SIGQUIT)
233: signal(SIGQUIT, PETSC_SIGNAL_CAST PetscSignalHandler_Private);
234: #endif
235: #if !defined(PETSC_MISSING_SIGSEGV)
236: signal(SIGSEGV, 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_SIGSYS)
293: signal(SIGSYS, 0);
294: #endif
295: #if !defined(PETSC_MISSING_SIGTERM)
296: signal(SIGTERM, 0);
297: #endif
298: #if !defined(PETSC_MISSING_SIGTRAP)
299: signal(SIGTRAP, 0);
300: #endif
301: #if !defined(PETSC_MISSING_SIGTSTP)
302: /* signal(SIGTSTP, 0); */
303: #endif
304: #if !defined(PETSC_MISSING_SIGURG)
305: signal(SIGURG, 0);
306: #endif
307: #if !defined(PETSC_MISSING_SIGUSR1)
308: /* signal(SIGUSR1, 0); */
309: #endif
310: #if !defined(PETSC_MISSING_SIGUSR2)
311: /* signal(SIGUSR2, 0); */
312: #endif
313: SignalSet = PETSC_FALSE;
314: }
315: PetscNew(struct SH,&newsh);
316: if (sh) {
317: if (sh->classid != SIGNAL_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_COR,"Signal object has been corrupted");
318: newsh->previous = sh;
319: }
320: else {newsh->previous = 0;}
321: newsh->handler = routine;
322: newsh->ctx = ctx;
323: newsh->classid = SIGNAL_CLASSID;
324: sh = newsh;
325: return(0);
326: }
330: /*@
331: PetscPopSignalHandler - Removes the most last signal handler that was pushed.
332: If no signal handlers are left on the stack it will remove the PETSc signal handler.
333: (That is PETSc will no longer catch signals).
335: Not Collective
337: Level: developer
339: Concepts: signal handler^setting
341: .seealso: PetscPushSignalHandler()
343: @*/
344: PetscErrorCode PetscPopSignalHandler(void)
345: {
346: struct SH *tmp;
349: if (!sh) return(0);
350: if (sh->classid != SIGNAL_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_COR,"Signal object has been corrupted");
352: tmp = sh;
353: sh = sh->previous;
354: PetscFreeVoid(tmp);
355: if (!sh || !sh->handler) {
356: #if !defined(PETSC_MISSING_SIGALRM)
357: /* signal(SIGALRM, 0); */
358: #endif
359: #if !defined(PETSC_MISSING_SIGBUS)
360: signal(SIGBUS, 0);
361: #endif
362: #if !defined(PETSC_MISSING_SIGCONT)
363: /* signal(SIGCONT, 0); */
364: #endif
365: #if !defined(PETSC_MISSING_SIGFPE)
366: signal(SIGFPE, 0);
367: #endif
368: #if !defined(PETSC_MISSING_SIGHUP)
369: signal(SIGHUP, 0);
370: #endif
371: #if !defined(PETSC_MISSING_SIGILL)
372: signal(SIGILL, 0);
373: #endif
374: #if !defined(PETSC_MISSING_SIGINT)
375: /* signal(SIGINT, 0); */
376: #endif
377: #if !defined(PETSC_MISSING_SIGPIPE)
378: signal(SIGPIPE, 0);
379: #endif
380: #if !defined(PETSC_MISSING_SIGQUIT)
381: signal(SIGQUIT, 0);
382: #endif
383: #if !defined(PETSC_MISSING_SIGSEGV)
384: signal(SIGSEGV, 0);
385: #endif
386: #if !defined(PETSC_MISSING_SIGSYS)
387: signal(SIGSYS, 0);
388: #endif
389: #if !defined(PETSC_MISSING_SIGTERM)
390: signal(SIGTERM, 0);
391: #endif
392: #if !defined(PETSC_MISSING_SIGTRAP)
393: signal(SIGTRAP, 0);
394: #endif
395: #if !defined(PETSC_MISSING_SIGTSTP)
396: /* signal(SIGTSTP, 0); */
397: #endif
398: #if !defined(PETSC_MISSING_SIGURG)
399: signal(SIGURG, 0);
400: #endif
401: #if !defined(PETSC_MISSING_SIGUSR1)
402: /* signal(SIGUSR1, 0); */
403: #endif
404: #if !defined(PETSC_MISSING_SIGUSR2)
405: /* signal(SIGUSR2, 0); */
406: #endif
407: SignalSet = PETSC_FALSE;
408: } else {
409: SignalSet = PETSC_TRUE;
410: }
411: return(0);
412: }