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 struct SH { 12 int cookie; 13 PetscErrorCode (*handler)(int,void *); 14 void *ctx; 15 struct SH* previous; 16 }; 17 static struct SH* sh = 0; 18 static PetscTruth 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 ierr = (*sh->handler)(sig,sh->ctx); 53 } 54 if (ierr) MPI_Abort(PETSC_COMM_WORLD,0); 55 } 56 EXTERN_C_END 57 58 #undef __FUNCT__ 59 #define __FUNCT__ "PetscDefaultSignalHandler" 60 /*@ 61 PetscDefaultSignalHandler - Default signal handler. 62 63 Not Collective 64 65 Level: advanced 66 67 Input Parameters: 68 + sig - signal value 69 - ptr - unused pointer 70 71 Concepts: signal handler^default 72 73 @*/ 74 PetscErrorCode PETSC_DLLEXPORT PetscDefaultSignalHandler(int sig,void *ptr) 75 { 76 PetscErrorCode ierr; 77 const char *SIGNAME[64]; 78 79 PetscFunctionBegin; 80 SIGNAME[0] = "Unknown signal"; 81 #if !defined(PETSC_MISSING_SIGABRT) 82 SIGNAME[SIGABRT] = "Abort"; 83 #endif 84 #if !defined(PETSC_MISSING_SIGALRM) 85 /* SIGNAME[SIGALRM] = "Alarm"; */ 86 #endif 87 #if !defined(PETSC_MISSING_SIGBUS) 88 SIGNAME[SIGBUS] = "BUS: Bus Error, possibly illegal memory access"; 89 #endif 90 #if !defined(PETSC_MISSING_SIGCHLD) 91 SIGNAME[SIGCHLD] = "CHLD"; 92 #endif 93 #if !defined(PETSC_MISSING_SIGCONT) 94 SIGNAME[SIGCONT] = "CONT"; 95 #endif 96 #if !defined(PETSC_MISSING_SIGFPE) 97 SIGNAME[SIGFPE] = "FPE: Floating Point Exception,probably divide by zero"; 98 #endif 99 #if !defined(PETSC_MISSING_SIGHUP) 100 SIGNAME[SIGHUP] = "Hang up"; 101 #endif 102 #if !defined(PETSC_MISSING_SIGILL) 103 SIGNAME[SIGILL] = "Illegal instruction"; 104 #endif 105 #if !defined(PETSC_MISSING_SIGINT) 106 /* SIGNAME[SIGINT] = "Interrupt"; */ 107 #endif 108 #if !defined(PETSC_MISSING_SIGKILL) 109 SIGNAME[SIGKILL] = "Kill"; 110 #endif 111 #if !defined(PETSC_MISSING_SIGPIPE) 112 SIGNAME[SIGPIPE] = "Broken Pipe"; 113 #endif 114 #if !defined(PETSC_MISSING_SIGQUIT) 115 SIGNAME[SIGQUIT] = "Quit"; 116 #endif 117 #if !defined(PETSC_MISSING_SIGSEGV) 118 SIGNAME[SIGSEGV] = "SEGV: Segmentation Violation, probably memory access out of range"; 119 #endif 120 #if !defined(PETSC_MISSING_SIGSYS) 121 SIGNAME[SIGSYS] = "SYS"; 122 #endif 123 #if !defined(PETSC_MISSING_SIGTERM) 124 SIGNAME[SIGTERM] = "Terminate"; 125 #endif 126 #if !defined(PETSC_MISSING_SIGTRAP) 127 SIGNAME[SIGTRAP] = "TRAP"; 128 #endif 129 #if !defined(PETSC_MISSING_SIGTSTP) 130 SIGNAME[SIGTSTP] = "TSTP"; 131 #endif 132 #if !defined(PETSC_MISSING_SIGURG) 133 SIGNAME[SIGURG] = "URG"; 134 #endif 135 #if !defined(PETSC_MISSING_SIGUSR1) 136 SIGNAME[SIGUSR1] = "User 1"; 137 #endif 138 #if !defined(PETSC_MISSING_SIGUSR2) 139 SIGNAME[SIGUSR2] = "User 2"; 140 #endif 141 142 signal(sig,SIG_DFL); 143 if (sig >= 0 && sig <= 20) { 144 (*PetscErrorPrintf)("Caught signal number %d %s\n",sig,SIGNAME[sig]); 145 } else { 146 (*PetscErrorPrintf)("Caught signal\n"); 147 } 148 (*PetscErrorPrintf)("Try option -start_in_debugger or -on_error_attach_debugger\n"); 149 #if defined(PETSC_USE_DEBUG) 150 if (!PetscStackActive) { 151 (*PetscErrorPrintf)(" or try option -log_stack\n"); 152 } else { 153 PetscStackPop; /* remove stack frames for error handlers */ 154 PetscStackPop; 155 (*PetscErrorPrintf)("likely location of problem given in stack below\n"); 156 (*PetscErrorPrintf)("--------------- Stack Frames ---------------\n"); 157 PetscStackView(PETSC_VIEWER_STDOUT_SELF); 158 (*PetscErrorPrintf)("--------------------------------------------\n"); 159 } 160 #endif 161 #if !defined(PETSC_USE_DEBUG) 162 (*PetscErrorPrintf)("configure using --with-debugging=yes, recompile, link, and run \n"); 163 (*PetscErrorPrintf)("to get more information on the crash.\n"); 164 #endif 165 ierr = PetscError(0,"User provided function"," unknown file","unknown directory",PETSC_ERR_SIG,1," "); 166 MPI_Abort(PETSC_COMM_WORLD,(int)ierr); 167 PetscFunctionReturn(0); 168 } 169 170 #if !defined(PETSC_SIGNAL_CAST) 171 #define PETSC_SIGNAL_CAST 172 #endif 173 174 #undef __FUNCT__ 175 #define __FUNCT__ "PetscPushSignalHandler" 176 /*@C 177 PetscPushSignalHandler - Catches the usual fatal errors and 178 calls a user-provided routine. 179 180 Not Collective 181 182 Input Parameter: 183 + routine - routine to call when a signal is received 184 - ctx - optional context needed by the routine 185 186 Level: developer 187 188 Concepts: signal handler^setting 189 190 .seealso: PetscPopSignalHandler(), PetscDefaultSignalHandler() 191 192 @*/ 193 PetscErrorCode PETSC_DLLEXPORT PetscPushSignalHandler(PetscErrorCode (*routine)(int,void*),void* ctx) 194 { 195 struct SH *newsh; 196 PetscErrorCode ierr; 197 198 PetscFunctionBegin; 199 if (!SignalSet && routine) { 200 /* Do not catch ABRT, CHLD, KILL */ 201 #if !defined(PETSC_MISSING_SIGALRM) 202 /* signal(SIGALRM, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */ 203 #endif 204 #if !defined(PETSC_MISSING_SIGBUS) 205 signal(SIGBUS, PETSC_SIGNAL_CAST PetscSignalHandler_Private); 206 #endif 207 #if !defined(PETSC_MISSING_SIGCONT) 208 /*signal(SIGCONT, PETSC_SIGNAL_CAST PetscSignalHandler_Private);*/ 209 #endif 210 #if !defined(PETSC_MISSING_SIGFPE) 211 signal(SIGFPE, PETSC_SIGNAL_CAST PetscSignalHandler_Private); 212 #endif 213 #if !defined(PETSC_MISSING_SIGHUP) 214 signal(SIGHUP, PETSC_SIGNAL_CAST PetscSignalHandler_Private); 215 #endif 216 #if !defined(PETSC_MISSING_SIGILL) 217 signal(SIGILL, PETSC_SIGNAL_CAST PetscSignalHandler_Private); 218 #endif 219 #if !defined(PETSC_MISSING_SIGINT) 220 /* signal(SIGINT, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */ 221 #endif 222 #if !defined(PETSC_MISSING_SIGPIPE) 223 signal(SIGPIPE, PETSC_SIGNAL_CAST PetscSignalHandler_Private); 224 #endif 225 #if !defined(PETSC_MISSING_SIGQUIT) 226 signal(SIGQUIT, PETSC_SIGNAL_CAST PetscSignalHandler_Private); 227 #endif 228 #if !defined(PETSC_MISSING_SIGSEGV) 229 signal(SIGSEGV, PETSC_SIGNAL_CAST PetscSignalHandler_Private); 230 #endif 231 #if !defined(PETSC_MISSING_SIGSYS) 232 signal(SIGSYS, PETSC_SIGNAL_CAST PetscSignalHandler_Private); 233 #endif 234 #if !defined(PETSC_MISSING_SIGTERM) 235 signal(SIGTERM, PETSC_SIGNAL_CAST PetscSignalHandler_Private); 236 #endif 237 #if !defined(PETSC_MISSING_SIGTRAP) 238 signal(SIGTRAP, PETSC_SIGNAL_CAST PetscSignalHandler_Private); 239 #endif 240 #if !defined(PETSC_MISSING_SIGTSTP) 241 /* signal(SIGTSTP, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */ 242 #endif 243 #if !defined(PETSC_MISSING_SIGURG) 244 signal(SIGURG, PETSC_SIGNAL_CAST PetscSignalHandler_Private); 245 #endif 246 #if !defined(PETSC_MISSING_SIGUSR1) 247 /* signal(SIGUSR1, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */ 248 #endif 249 #if !defined(PETSC_MISSING_SIGUSR2) 250 /* signal(SIGUSR2, PETSC_SIGNAL_CAST PetscSignalHandler_Private); */ 251 #endif 252 SignalSet = PETSC_TRUE; 253 } 254 if (!routine) { 255 #if !defined(PETSC_MISSING_SIGALRM) 256 /* signal(SIGALRM, 0); */ 257 #endif 258 #if !defined(PETSC_MISSING_SIGBUS) 259 signal(SIGBUS, 0); 260 #endif 261 #if !defined(PETSC_MISSING_SIGCONT) 262 /* signal(SIGCONT, 0); */ 263 #endif 264 #if !defined(PETSC_MISSING_SIGFPE) 265 signal(SIGFPE, 0); 266 #endif 267 #if !defined(PETSC_MISSING_SIGHUP) 268 signal(SIGHUP, 0); 269 #endif 270 #if !defined(PETSC_MISSING_SIGILL) 271 signal(SIGILL, 0); 272 #endif 273 #if !defined(PETSC_MISSING_SIGINT) 274 /* signal(SIGINT, 0); */ 275 #endif 276 #if !defined(PETSC_MISSING_SIGPIPE) 277 signal(SIGPIPE, 0); 278 #endif 279 #if !defined(PETSC_MISSING_SIGQUIT) 280 signal(SIGQUIT, 0); 281 #endif 282 #if !defined(PETSC_MISSING_SIGSEGV) 283 signal(SIGSEGV, 0); 284 #endif 285 #if !defined(PETSC_MISSING_SIGSYS) 286 signal(SIGSYS, 0); 287 #endif 288 #if !defined(PETSC_MISSING_SIGTERM) 289 signal(SIGTERM, 0); 290 #endif 291 #if !defined(PETSC_MISSING_SIGTRAP) 292 signal(SIGTRAP, 0); 293 #endif 294 #if !defined(PETSC_MISSING_SIGTSTP) 295 /* signal(SIGTSTP, 0); */ 296 #endif 297 #if !defined(PETSC_MISSING_SIGURG) 298 signal(SIGURG, 0); 299 #endif 300 #if !defined(PETSC_MISSING_SIGUSR1) 301 /* signal(SIGUSR1, 0); */ 302 #endif 303 #if !defined(PETSC_MISSING_SIGUSR2) 304 /* signal(SIGUSR2, 0); */ 305 #endif 306 SignalSet = PETSC_FALSE; 307 } 308 ierr = PetscNew(struct SH,&newsh);CHKERRQ(ierr); 309 if (sh) {newsh->previous = sh;} 310 else {newsh->previous = 0;} 311 newsh->handler = routine; 312 newsh->ctx = ctx; 313 sh = newsh; 314 PetscFunctionReturn(0); 315 } 316 317 #undef __FUNCT__ 318 #define __FUNCT__ "PetscPopSignalHandler" 319 /*@ 320 PetscPopSignalHandler - Removes the most last signal handler that was pushed. 321 If no signal handlers are left on the stack it will remove the PETSc signal handler. 322 (That is PETSc will no longer catch signals). 323 324 Not Collective 325 326 Level: developer 327 328 Note: NO ERROR CODES RETURNED BY THIS FUNCTION 329 330 Concepts: signal handler^setting 331 332 .seealso: PetscPushSignalHandler() 333 334 @*/ 335 PetscErrorCode PETSC_DLLEXPORT PetscPopSignalHandler(void) 336 { 337 struct SH *tmp; 338 339 PetscFunctionBegin; 340 if (!sh) PetscFunctionReturn(0); 341 tmp = sh; 342 sh = sh->previous; 343 PetscFreeVoid(tmp); 344 if (!sh || !sh->handler) { 345 #if !defined(PETSC_MISSING_SIGALRM) 346 /* signal(SIGALRM, 0); */ 347 #endif 348 #if !defined(PETSC_MISSING_SIGBUS) 349 signal(SIGBUS, 0); 350 #endif 351 #if !defined(PETSC_MISSING_SIGCONT) 352 /* signal(SIGCONT, 0); */ 353 #endif 354 #if !defined(PETSC_MISSING_SIGFPE) 355 signal(SIGFPE, 0); 356 #endif 357 #if !defined(PETSC_MISSING_SIGHUP) 358 signal(SIGHUP, 0); 359 #endif 360 #if !defined(PETSC_MISSING_SIGILL) 361 signal(SIGILL, 0); 362 #endif 363 #if !defined(PETSC_MISSING_SIGINT) 364 /* signal(SIGINT, 0); */ 365 #endif 366 #if !defined(PETSC_MISSING_SIGPIPE) 367 signal(SIGPIPE, 0); 368 #endif 369 #if !defined(PETSC_MISSING_SIGQUIT) 370 signal(SIGQUIT, 0); 371 #endif 372 #if !defined(PETSC_MISSING_SIGSEGV) 373 signal(SIGSEGV, 0); 374 #endif 375 #if !defined(PETSC_MISSING_SIGSYS) 376 signal(SIGSYS, 0); 377 #endif 378 #if !defined(PETSC_MISSING_SIGTERM) 379 signal(SIGTERM, 0); 380 #endif 381 #if !defined(PETSC_MISSING_SIGTRAP) 382 signal(SIGTRAP, 0); 383 #endif 384 #if !defined(PETSC_MISSING_SIGTSTP) 385 /* signal(SIGTSTP, 0); */ 386 #endif 387 #if !defined(PETSC_MISSING_SIGURG) 388 signal(SIGURG, 0); 389 #endif 390 #if !defined(PETSC_MISSING_SIGUSR1) 391 /* signal(SIGUSR1, 0); */ 392 #endif 393 #if !defined(PETSC_MISSING_SIGUSR2) 394 /* signal(SIGUSR2, 0); */ 395 #endif 396 SignalSet = PETSC_FALSE; 397 } else { 398 SignalSet = PETSC_TRUE; 399 } 400 PetscFunctionReturn(0); 401 } 402 403 404 405 406