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 <signal.h> 7 #include "petsc.h" /*I "petsc.h" I*/ 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"; 104 #endif 105 #if !defined(PETSC_MISSING_SIGILL) 106 SIGNAME[SIGILL] = "Illegal instruction"; 107 #endif 108 #if !defined(PETSC_MISSING_SIGINT) 109 /* SIGNAME[SIGINT] = "Interrupt"; */ 110 #endif 111 #if !defined(PETSC_MISSING_SIGKILL) 112 SIGNAME[SIGKILL] = "Kill"; 113 #endif 114 #if !defined(PETSC_MISSING_SIGPIPE) 115 SIGNAME[SIGPIPE] = "Broken Pipe"; 116 #endif 117 #if !defined(PETSC_MISSING_SIGQUIT) 118 SIGNAME[SIGQUIT] = "Quit"; 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";*/ 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 #if defined(PETSC_USE_DEBUG) 153 if (!PetscStackActive) { 154 (*PetscErrorPrintf)(" or try option -log_stack\n"); 155 } else { 156 PetscStackPop; /* remove stack frames for error handlers */ 157 PetscStackPop; 158 (*PetscErrorPrintf)("likely location of problem given in stack below\n"); 159 (*PetscErrorPrintf)("--------------- Stack Frames ---------------\n"); 160 PetscStackView(PETSC_VIEWER_STDOUT_SELF); 161 (*PetscErrorPrintf)("--------------------------------------------\n"); 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 } 205 if (!SignalSet && routine) { 206 /* Do not catch ABRT, CHLD, KILL */ 207 #if !defined(PETSC_MISSING_SIGALRM) 208 /* signal(SIGALRM, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */ 209 #endif 210 #if !defined(PETSC_MISSING_SIGBUS) 211 signal(SIGBUS, PETSC_SIGNAL_CAST PetscSignalHandler_Private); 212 #endif 213 #if !defined(PETSC_MISSING_SIGCONT) 214 /*signal(SIGCONT, PETSC_SIGNAL_CAST PetscSignalHandler_Private);*/ 215 #endif 216 #if !defined(PETSC_MISSING_SIGFPE) 217 signal(SIGFPE, PETSC_SIGNAL_CAST PetscSignalHandler_Private); 218 #endif 219 #if !defined(PETSC_MISSING_SIGHUP) 220 signal(SIGHUP, PETSC_SIGNAL_CAST PetscSignalHandler_Private); 221 #endif 222 #if !defined(PETSC_MISSING_SIGILL) 223 signal(SIGILL, PETSC_SIGNAL_CAST PetscSignalHandler_Private); 224 #endif 225 #if !defined(PETSC_MISSING_SIGINT) 226 /* signal(SIGINT, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */ 227 #endif 228 #if !defined(PETSC_MISSING_SIGPIPE) 229 signal(SIGPIPE, PETSC_SIGNAL_CAST PetscSignalHandler_Private); 230 #endif 231 #if !defined(PETSC_MISSING_SIGQUIT) 232 signal(SIGQUIT, PETSC_SIGNAL_CAST PetscSignalHandler_Private); 233 #endif 234 #if !defined(PETSC_MISSING_SIGSEGV) 235 signal(SIGSEGV, PETSC_SIGNAL_CAST PetscSignalHandler_Private); 236 #endif 237 #if !defined(PETSC_MISSING_SIGSYS) 238 signal(SIGSYS, PETSC_SIGNAL_CAST PetscSignalHandler_Private); 239 #endif 240 #if !defined(PETSC_MISSING_SIGTERM) 241 signal(SIGTERM, PETSC_SIGNAL_CAST PetscSignalHandler_Private); 242 #endif 243 #if !defined(PETSC_MISSING_SIGTRAP) 244 signal(SIGTRAP, PETSC_SIGNAL_CAST PetscSignalHandler_Private); 245 #endif 246 #if !defined(PETSC_MISSING_SIGTSTP) 247 /* signal(SIGTSTP, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */ 248 #endif 249 #if !defined(PETSC_MISSING_SIGURG) 250 signal(SIGURG, PETSC_SIGNAL_CAST PetscSignalHandler_Private); 251 #endif 252 #if !defined(PETSC_MISSING_SIGUSR1) 253 /* signal(SIGUSR1, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */ 254 #endif 255 #if !defined(PETSC_MISSING_SIGUSR2) 256 /* signal(SIGUSR2, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */ 257 #endif 258 SignalSet = PETSC_TRUE; 259 } 260 if (!routine) { 261 #if !defined(PETSC_MISSING_SIGALRM) 262 /* signal(SIGALRM, 0); */ 263 #endif 264 #if !defined(PETSC_MISSING_SIGBUS) 265 signal(SIGBUS, 0); 266 #endif 267 #if !defined(PETSC_MISSING_SIGCONT) 268 /* signal(SIGCONT, 0); */ 269 #endif 270 #if !defined(PETSC_MISSING_SIGFPE) 271 signal(SIGFPE, 0); 272 #endif 273 #if !defined(PETSC_MISSING_SIGHUP) 274 signal(SIGHUP, 0); 275 #endif 276 #if !defined(PETSC_MISSING_SIGILL) 277 signal(SIGILL, 0); 278 #endif 279 #if !defined(PETSC_MISSING_SIGINT) 280 /* signal(SIGINT, 0); */ 281 #endif 282 #if !defined(PETSC_MISSING_SIGPIPE) 283 signal(SIGPIPE, 0); 284 #endif 285 #if !defined(PETSC_MISSING_SIGQUIT) 286 signal(SIGQUIT, 0); 287 #endif 288 #if !defined(PETSC_MISSING_SIGSEGV) 289 signal(SIGSEGV, 0); 290 #endif 291 #if !defined(PETSC_MISSING_SIGSYS) 292 signal(SIGSYS, 0); 293 #endif 294 #if !defined(PETSC_MISSING_SIGTERM) 295 signal(SIGTERM, 0); 296 #endif 297 #if !defined(PETSC_MISSING_SIGTRAP) 298 signal(SIGTRAP, 0); 299 #endif 300 #if !defined(PETSC_MISSING_SIGTSTP) 301 /* signal(SIGTSTP, 0); */ 302 #endif 303 #if !defined(PETSC_MISSING_SIGURG) 304 signal(SIGURG, 0); 305 #endif 306 #if !defined(PETSC_MISSING_SIGUSR1) 307 /* signal(SIGUSR1, 0); */ 308 #endif 309 #if !defined(PETSC_MISSING_SIGUSR2) 310 /* signal(SIGUSR2, 0); */ 311 #endif 312 SignalSet = PETSC_FALSE; 313 } 314 ierr = PetscNew(struct SH,&newsh);CHKERRQ(ierr); 315 if (sh) { 316 if (sh->cookie != SIGNAL_COOKIE) SETERRQ(PETSC_ERR_COR,"Signal object has been corrupted"); 317 newsh->previous = sh; 318 } 319 else {newsh->previous = 0;} 320 newsh->handler = routine; 321 newsh->ctx = ctx; 322 newsh->cookie = SIGNAL_COOKIE; 323 sh = newsh; 324 PetscFunctionReturn(0); 325 } 326 327 #undef __FUNCT__ 328 #define __FUNCT__ "PetscPopSignalHandler" 329 /*@ 330 PetscPopSignalHandler - Removes the most last signal handler that was pushed. 331 If no signal handlers are left on the stack it will remove the PETSc signal handler. 332 (That is PETSc will no longer catch signals). 333 334 Not Collective 335 336 Level: developer 337 338 Concepts: signal handler^setting 339 340 .seealso: PetscPushSignalHandler() 341 342 @*/ 343 PetscErrorCode PETSC_DLLEXPORT PetscPopSignalHandler(void) 344 { 345 struct SH *tmp; 346 347 PetscFunctionBegin; 348 if (!sh) PetscFunctionReturn(0); 349 if (sh->cookie != SIGNAL_COOKIE) SETERRQ(PETSC_ERR_COR,"Signal object has been corrupted"); 350 351 tmp = sh; 352 sh = sh->previous; 353 PetscFreeVoid(tmp); 354 if (!sh || !sh->handler) { 355 #if !defined(PETSC_MISSING_SIGALRM) 356 /* signal(SIGALRM, 0); */ 357 #endif 358 #if !defined(PETSC_MISSING_SIGBUS) 359 signal(SIGBUS, 0); 360 #endif 361 #if !defined(PETSC_MISSING_SIGCONT) 362 /* signal(SIGCONT, 0); */ 363 #endif 364 #if !defined(PETSC_MISSING_SIGFPE) 365 signal(SIGFPE, 0); 366 #endif 367 #if !defined(PETSC_MISSING_SIGHUP) 368 signal(SIGHUP, 0); 369 #endif 370 #if !defined(PETSC_MISSING_SIGILL) 371 signal(SIGILL, 0); 372 #endif 373 #if !defined(PETSC_MISSING_SIGINT) 374 /* signal(SIGINT, 0); */ 375 #endif 376 #if !defined(PETSC_MISSING_SIGPIPE) 377 signal(SIGPIPE, 0); 378 #endif 379 #if !defined(PETSC_MISSING_SIGQUIT) 380 signal(SIGQUIT, 0); 381 #endif 382 #if !defined(PETSC_MISSING_SIGSEGV) 383 signal(SIGSEGV, 0); 384 #endif 385 #if !defined(PETSC_MISSING_SIGSYS) 386 signal(SIGSYS, 0); 387 #endif 388 #if !defined(PETSC_MISSING_SIGTERM) 389 signal(SIGTERM, 0); 390 #endif 391 #if !defined(PETSC_MISSING_SIGTRAP) 392 signal(SIGTRAP, 0); 393 #endif 394 #if !defined(PETSC_MISSING_SIGTSTP) 395 /* signal(SIGTSTP, 0); */ 396 #endif 397 #if !defined(PETSC_MISSING_SIGURG) 398 signal(SIGURG, 0); 399 #endif 400 #if !defined(PETSC_MISSING_SIGUSR1) 401 /* signal(SIGUSR1, 0); */ 402 #endif 403 #if !defined(PETSC_MISSING_SIGUSR2) 404 /* signal(SIGUSR2, 0); */ 405 #endif 406 SignalSet = PETSC_FALSE; 407 } else { 408 SignalSet = PETSC_TRUE; 409 } 410 PetscFunctionReturn(0); 411 } 412 413 414 415 416