1 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> 8 9 static PetscClassId SIGNAL_CLASSID = 0; 10 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; 19 20 21 22 EXTERN_C_BEGIN 23 #undef __FUNCT__ 24 #define __FUNCT__ "PetscSignalHandler_Private" 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 - ?? 34 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". 38 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 { 46 PetscErrorCode ierr; 47 48 PetscFunctionBegin; 49 if (!sh || !sh->handler) { 50 ierr = 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 ierr = (*sh->handler)(sig,sh->ctx); 54 } 55 if (ierr) MPI_Abort(PETSC_COMM_WORLD,0); 56 } 57 EXTERN_C_END 58 59 #undef __FUNCT__ 60 #define __FUNCT__ "PetscDefaultSignalHandler" 61 /*@ 62 PetscDefaultSignalHandler - Default signal handler. 63 64 Not Collective 65 66 Level: advanced 67 68 Input Parameters: 69 + sig - signal value 70 - ptr - unused pointer 71 72 Concepts: signal handler^default 73 74 @*/ 75 PetscErrorCode PetscDefaultSignalHandler(int sig,void *ptr) 76 { 77 PetscErrorCode ierr; 78 const char *SIGNAME[64]; 79 80 PetscFunctionBegin; 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 142 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/petsc-as/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) && !defined(PETSC_USE_PTHREAD) 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(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 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 PetscPushSignalHandler(PetscErrorCode (*routine)(int,void*),void* ctx) 197 { 198 struct SH *newsh; 199 PetscErrorCode ierr; 200 201 PetscFunctionBegin; 202 if (!SIGNAL_CLASSID) { 203 /* ierr = PetscClassIdRegister("Signal",&SIGNAL_CLASSID);CHKERRQ(ierr); */ 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 ierr = PetscNew(struct SH,&newsh);CHKERRQ(ierr); 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 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 PetscPopSignalHandler(void) 345 { 346 struct SH *tmp; 347 348 PetscFunctionBegin; 349 if (!sh) PetscFunctionReturn(0); 350 if (sh->classid != SIGNAL_CLASSID) SETERRQ(PETSC_COMM_SELF,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