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" /*I "petsc.h" I*/ 7 #include <signal.h> 8 #include "petscsys.h" 9 #include "petscfix.h" 10 11 static PetscCookie SIGNAL_COOKIE = 0; 12 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; 21 22 23 24 EXTERN_C_BEGIN 25 #undef __FUNCT__ 26 #define __FUNCT__ "PetscSignalHandler_Private" 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 - ?? 36 37 Note: this is declared extern "C" because it is passed to the system routine signal() 38 which is an extern "C" routine. The Solaris 2.7 OS compilers require that this be 39 extern "C". 40 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 { 48 PetscErrorCode ierr; 49 50 PetscFunctionBegin; 51 if (!sh || !sh->handler) { 52 ierr = 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 ierr = (*sh->handler)(sig,sh->ctx); 56 } 57 if (ierr) MPI_Abort(PETSC_COMM_WORLD,0); 58 } 59 EXTERN_C_END 60 61 #undef __FUNCT__ 62 #define __FUNCT__ "PetscDefaultSignalHandler" 63 /*@ 64 PetscDefaultSignalHandler - Default signal handler. 65 66 Not Collective 67 68 Level: advanced 69 70 Input Parameters: 71 + sig - signal value 72 - ptr - unused pointer 73 74 Concepts: signal handler^default 75 76 @*/ 77 PetscErrorCode PETSC_DLLEXPORT PetscDefaultSignalHandler(int sig,void *ptr) 78 { 79 PetscErrorCode ierr; 80 const char *SIGNAME[64]; 81 82 PetscFunctionBegin; 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 144 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 ierr = PetscError(0,"User provided function"," unknown file","unknown directory",PETSC_ERR_SIG,1,PETSC_NULL); 171 MPI_Abort(PETSC_COMM_WORLD,(int)ierr); 172 PetscFunctionReturn(0); 173 } 174 175 #if !defined(PETSC_SIGNAL_CAST) 176 #define PETSC_SIGNAL_CAST 177 #endif 178 179 #undef __FUNCT__ 180 #define __FUNCT__ "PetscPushSignalHandler" 181 /*@C 182 PetscPushSignalHandler - Catches the usual fatal errors and 183 calls a user-provided routine. 184 185 Not Collective 186 187 Input Parameter: 188 + routine - routine to call when a signal is received 189 - ctx - optional context needed by the routine 190 191 Level: developer 192 193 Concepts: signal handler^setting 194 195 .seealso: PetscPopSignalHandler(), PetscDefaultSignalHandler() 196 197 @*/ 198 PetscErrorCode PETSC_DLLEXPORT PetscPushSignalHandler(PetscErrorCode (*routine)(int,void*),void* ctx) 199 { 200 struct SH *newsh; 201 PetscErrorCode ierr; 202 203 PetscFunctionBegin; 204 if (!SIGNAL_COOKIE) { 205 /* ierr = PetscLogClassRegister(&SIGNAL_COOKIE,"Signal");CHKERRQ(ierr); */ 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 ierr = PetscNew(struct SH,&newsh);CHKERRQ(ierr); 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 PetscFunctionReturn(0); 328 } 329 330 #undef __FUNCT__ 331 #define __FUNCT__ "PetscPopSignalHandler" 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). 336 337 Not Collective 338 339 Level: developer 340 341 Concepts: signal handler^setting 342 343 .seealso: PetscPushSignalHandler() 344 345 @*/ 346 PetscErrorCode PETSC_DLLEXPORT PetscPopSignalHandler(void) 347 { 348 struct SH *tmp; 349 350 PetscFunctionBegin; 351 if (!sh) PetscFunctionReturn(0); 352 if (sh->cookie != SIGNAL_COOKIE) SETERRQ(PETSC_ERR_COR,"Signal object has been corrupted"); 353 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 PetscFunctionReturn(0); 414 } 415 416 417 418 419