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