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 try http://valgrind.org on linux to find memory corruption errors\n"); 154 #if defined(PETSC_USE_DEBUG) 155 if (!PetscStackActive) { 156 (*PetscErrorPrintf)(" or try option -log_stack\n"); 157 } else { 158 PetscStackPop; /* remove stack frames for error handlers */ 159 PetscStackPop; 160 (*PetscErrorPrintf)("likely location of problem given in stack below\n"); 161 (*PetscErrorPrintf)("--------------------- Stack Frames ------------------------------------\n"); 162 PetscStackView(PETSC_VIEWER_STDOUT_SELF); 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 ierr = PetscError(0,"User provided function"," unknown file","unknown directory",PETSC_ERR_SIG,1,PETSC_NULL); 170 MPI_Abort(PETSC_COMM_WORLD,(int)ierr); 171 PetscFunctionReturn(0); 172 } 173 174 #if !defined(PETSC_SIGNAL_CAST) 175 #define PETSC_SIGNAL_CAST 176 #endif 177 178 #undef __FUNCT__ 179 #define __FUNCT__ "PetscPushSignalHandler" 180 /*@C 181 PetscPushSignalHandler - Catches the usual fatal errors and 182 calls a user-provided routine. 183 184 Not Collective 185 186 Input Parameter: 187 + routine - routine to call when a signal is received 188 - ctx - optional context needed by the routine 189 190 Level: developer 191 192 Concepts: signal handler^setting 193 194 .seealso: PetscPopSignalHandler(), PetscDefaultSignalHandler() 195 196 @*/ 197 PetscErrorCode PETSC_DLLEXPORT PetscPushSignalHandler(PetscErrorCode (*routine)(int,void*),void* ctx) 198 { 199 struct SH *newsh; 200 PetscErrorCode ierr; 201 202 PetscFunctionBegin; 203 if (!SIGNAL_COOKIE) { 204 /* ierr = PetscLogClassRegister(&SIGNAL_COOKIE,"Signal");CHKERRQ(ierr); */ 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 ierr = PetscNew(struct SH,&newsh);CHKERRQ(ierr); 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 PetscFunctionReturn(0); 327 } 328 329 #undef __FUNCT__ 330 #define __FUNCT__ "PetscPopSignalHandler" 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). 335 336 Not Collective 337 338 Level: developer 339 340 Concepts: signal handler^setting 341 342 .seealso: PetscPushSignalHandler() 343 344 @*/ 345 PetscErrorCode PETSC_DLLEXPORT PetscPopSignalHandler(void) 346 { 347 struct SH *tmp; 348 349 PetscFunctionBegin; 350 if (!sh) PetscFunctionReturn(0); 351 if (sh->cookie != SIGNAL_COOKIE) SETERRQ(PETSC_ERR_COR,"Signal object has been corrupted"); 352 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 PetscFunctionReturn(0); 413 } 414 415 416 417 418