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 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 } 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 ierr = PetscError(0,"User provided function"," unknown file","unknown directory",PETSC_ERR_SIG,1," "); 169 MPI_Abort(PETSC_COMM_WORLD,(int)ierr); 170 PetscFunctionReturn(0); 171 } 172 173 #if !defined(PETSC_SIGNAL_CAST) 174 #define PETSC_SIGNAL_CAST 175 #endif 176 177 #undef __FUNCT__ 178 #define __FUNCT__ "PetscPushSignalHandler" 179 /*@C 180 PetscPushSignalHandler - Catches the usual fatal errors and 181 calls a user-provided routine. 182 183 Not Collective 184 185 Input Parameter: 186 + routine - routine to call when a signal is received 187 - ctx - optional context needed by the routine 188 189 Level: developer 190 191 Concepts: signal handler^setting 192 193 .seealso: PetscPopSignalHandler(), PetscDefaultSignalHandler() 194 195 @*/ 196 PetscErrorCode PETSC_DLLEXPORT PetscPushSignalHandler(PetscErrorCode (*routine)(int,void*),void* ctx) 197 { 198 struct SH *newsh; 199 PetscErrorCode ierr; 200 201 PetscFunctionBegin; 202 if (!SIGNAL_COOKIE) { 203 /* ierr = PetscLogClassRegister(&SIGNAL_COOKIE,"Signal");CHKERRQ(ierr); */ 204 SIGNAL_COOKIE = 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 ierr = PetscNew(struct SH,&newsh);CHKERRQ(ierr); 316 if (sh) { 317 if (sh->cookie != SIGNAL_COOKIE) SETERRQ(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->cookie = SIGNAL_COOKIE; 324 sh = newsh; 325 PetscFunctionReturn(0); 326 } 327 328 #undef __FUNCT__ 329 #define __FUNCT__ "PetscPopSignalHandler" 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). 334 335 Not Collective 336 337 Level: developer 338 339 Concepts: signal handler^setting 340 341 .seealso: PetscPushSignalHandler() 342 343 @*/ 344 PetscErrorCode PETSC_DLLEXPORT PetscPopSignalHandler(void) 345 { 346 struct SH *tmp; 347 348 PetscFunctionBegin; 349 if (!sh) PetscFunctionReturn(0); 350 if (sh->cookie != SIGNAL_COOKIE) SETERRQ(PETSC_ERR_COR,"Signal object has been corrupted"); 351 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 PetscFunctionReturn(0); 412 } 413 414 415 416 417