1 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> /*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 PetscSignalHandler_Private - This is the signal handler called by the system. This calls 22 any signal handler set by PETSc or the application code. 23 24 Input Parameters: (depends on system) 25 . sig - integer code indicating the type of signal 26 . code - ?? 27 . sigcontext - ?? 28 . addr - ?? 29 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 { 37 PetscErrorCode ierr; 38 39 PetscFunctionBegin; 40 if (!sh || !sh->handler) ierr = 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 ierr = (*sh->handler)(sig,sh->ctx); 44 } 45 if (ierr) MPI_Abort(PETSC_COMM_WORLD,0); 46 } 47 48 /*@ 49 PetscSignalHandlerDefault - Default signal handler. 50 51 Not Collective 52 53 Level: advanced 54 55 Input Parameters: 56 + sig - signal value 57 - ptr - unused pointer 58 59 Concepts: signal handler^default 60 61 @*/ 62 PetscErrorCode PetscSignalHandlerDefault(int sig,void *ptr) 63 { 64 PetscErrorCode ierr; 65 const char *SIGNAME[64]; 66 67 PetscFunctionBegin; 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 130 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"); 135 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 ierr = 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 PetscFunctionReturn(0); 156 } 157 158 #if !defined(PETSC_SIGNAL_CAST) 159 #define PETSC_SIGNAL_CAST 160 #endif 161 162 /*@C 163 PetscPushSignalHandler - Catches the usual fatal errors and 164 calls a user-provided routine. 165 166 Not Collective 167 168 Input Parameter: 169 + routine - routine to call when a signal is received 170 - ctx - optional context needed by the routine 171 172 Level: developer 173 174 Concepts: signal handler^setting 175 176 .seealso: PetscPopSignalHandler(), PetscSignalHandlerDefault(), PetscPushErrorHandler() 177 178 @*/ 179 PetscErrorCode PetscPushSignalHandler(PetscErrorCode (*routine)(int,void*),void *ctx) 180 { 181 struct SH *newsh; 182 PetscErrorCode ierr; 183 184 PetscFunctionBegin; 185 if (!SIGNAL_CLASSID) { 186 /* ierr = PetscClassIdRegister("Signal",&SIGNAL_CLASSID);CHKERRQ(ierr); */ 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 ierr = PetscNew(&newsh);CHKERRQ(ierr); 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 PetscFunctionReturn(0); 308 } 309 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). 314 315 Not Collective 316 317 Level: developer 318 319 Concepts: signal handler^setting 320 321 .seealso: PetscPushSignalHandler() 322 323 @*/ 324 PetscErrorCode PetscPopSignalHandler(void) 325 { 326 struct SH *tmp; 327 PetscErrorCode ierr; 328 329 PetscFunctionBegin; 330 if (!sh) PetscFunctionReturn(0); 331 if (sh->classid != SIGNAL_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_COR,"Signal object has been corrupted"); 332 333 tmp = sh; 334 sh = sh->previous; 335 ierr = PetscFree(tmp);CHKERRQ(ierr); 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 PetscFunctionReturn(0); 393 } 394