1 /* 2 Code to handle PETSc starting up in debuggers,etc. 3 */ 4 5 #include <petscsys.h> /*I "petscsys.h" I*/ 6 #include <signal.h> 7 #if defined(PETSC_HAVE_UNISTD_H) 8 #include <unistd.h> 9 #endif 10 11 /* 12 These are the debugger and display used if the debugger is started up 13 */ 14 static char PetscDebugger[PETSC_MAX_PATH_LEN]; 15 static char DebugTerminal[PETSC_MAX_PATH_LEN]; 16 static PetscBool UseDebugTerminal = PETSC_TRUE; 17 PetscBool petscwaitonerrorflg = PETSC_FALSE; 18 PetscBool petscindebugger = PETSC_FALSE; 19 20 /*@C 21 PetscSetDebugTerminal - Sets the terminal to use for debugging. 22 23 Not Collective 24 25 Input Parameter: 26 . terminal - name of terminal and any flags required to execute a program. 27 For example xterm, "urxvt -e", "gnome-terminal -x". 28 On Apple MacOS you can use Terminal (note the capital T) 29 30 Options Database Key: 31 -debug_terminal terminal - use this terminal instead of the default 32 33 Level: developer 34 35 Notes: 36 You can start the debugger for all processes in the same GNU screen session. 37 38 mpiexec -n 4 ./myapp -start_in_debugger -debug_terminal "screen -X -S debug screen" 39 40 will open 4 windows in the session named "debug". 41 42 The default on Apple is Terminal, on other systems the default is xterm 43 44 Fortran Note: 45 This routine is not supported in Fortran. 46 47 .seealso: `PetscSetDebugger()` 48 @*/ 49 PetscErrorCode PetscSetDebugTerminal(const char terminal[]) 50 { 51 PetscBool xterm; 52 53 PetscFunctionBegin; 54 PetscCall(PetscStrncpy(DebugTerminal, terminal, sizeof(DebugTerminal))); 55 PetscCall(PetscStrcmp(terminal, "xterm", &xterm)); 56 if (xterm) PetscCall(PetscStrlcat(DebugTerminal, " -e", sizeof(DebugTerminal))); 57 PetscFunctionReturn(0); 58 } 59 60 /*@C 61 PetscSetDebugger - Sets options associated with the debugger. 62 63 Not Collective 64 65 Input Parameters: 66 + debugger - name of debugger, which should be in your path, 67 usually "lldb", "dbx", "gdb", "cuda-gdb", "idb", "xxgdb", "kdgb" or "ddd". Also, HP-UX 68 supports "xdb", and IBM rs6000 supports "xldb". 69 70 - usedebugterminal - flag to indicate debugger window, set to either PETSC_TRUE (to indicate 71 debugger should be started in a new terminal window) or PETSC_FALSE (to start debugger 72 in initial window (the option PETSC_FALSE makes no sense when using more 73 than one MPI process.) 74 75 Level: developer 76 77 Fortran Note: 78 This routine is not supported in Fortran. 79 80 .seealso: `PetscAttachDebugger()`, `PetscAttachDebuggerErrorHandler()`, `PetscSetDebugTerminal()` 81 @*/ 82 PetscErrorCode PetscSetDebugger(const char debugger[], PetscBool usedebugterminal) 83 { 84 PetscFunctionBegin; 85 if (debugger) PetscCall(PetscStrncpy(PetscDebugger, debugger, sizeof(PetscDebugger))); 86 if (UseDebugTerminal) UseDebugTerminal = usedebugterminal; 87 PetscFunctionReturn(0); 88 } 89 90 /*@C 91 PetscSetDefaultDebugger - Causes PETSc to use its default debugger and output terminal 92 93 Not collective 94 95 Level: developer 96 97 .seealso: `PetscSetDebugger()`, `PetscSetDebuggerFromString()` 98 @*/ 99 PetscErrorCode PetscSetDefaultDebugger(void) 100 { 101 PetscFunctionBegin; 102 #if defined(PETSC_USE_DEBUGGER) 103 PetscCall(PetscSetDebugger(PETSC_USE_DEBUGGER, PETSC_TRUE)); 104 #endif 105 #if defined(__APPLE__) 106 PetscCall(PetscSetDebugTerminal("Terminal")); 107 #else 108 PetscCall(PetscSetDebugTerminal("xterm")); 109 #endif 110 PetscFunctionReturn(0); 111 } 112 113 static PetscErrorCode PetscCheckDebugger_Private(const char defaultDbg[], const char string[], const char *debugger[]) 114 { 115 PetscBool exists; 116 char *f; 117 118 PetscFunctionBegin; 119 PetscCall(PetscStrstr(string, defaultDbg, &f)); 120 if (f) { 121 PetscCall(PetscTestFile(string, 'x', &exists)); 122 if (exists) *debugger = string; 123 else *debugger = defaultDbg; 124 } 125 PetscFunctionReturn(0); 126 } 127 128 /*@C 129 PetscSetDebuggerFromString - Set the complete path for the 130 debugger for PETSc to use. 131 132 Not collective 133 134 Level: developer 135 136 .seealso: `PetscSetDebugger()`, `PetscSetDefaultDebugger()` 137 @*/ 138 PetscErrorCode PetscSetDebuggerFromString(const char *string) 139 { 140 const char *debugger = NULL; 141 PetscBool useterminal = PETSC_TRUE; 142 char *f; 143 144 PetscFunctionBegin; 145 PetscCall(PetscStrstr(string, "noxterm", &f)); 146 if (f) useterminal = PETSC_FALSE; 147 PetscCall(PetscStrstr(string, "ddd", &f)); 148 if (f) useterminal = PETSC_FALSE; 149 PetscCall(PetscStrstr(string, "noterminal", &f)); 150 if (f) useterminal = PETSC_FALSE; 151 PetscCall(PetscCheckDebugger_Private("xdb", string, &debugger)); 152 PetscCall(PetscCheckDebugger_Private("dbx", string, &debugger)); 153 PetscCall(PetscCheckDebugger_Private("xldb", string, &debugger)); 154 PetscCall(PetscCheckDebugger_Private("gdb", string, &debugger)); 155 PetscCall(PetscCheckDebugger_Private("cuda-gdb", string, &debugger)); 156 PetscCall(PetscCheckDebugger_Private("idb", string, &debugger)); 157 PetscCall(PetscCheckDebugger_Private("xxgdb", string, &debugger)); 158 PetscCall(PetscCheckDebugger_Private("ddd", string, &debugger)); 159 PetscCall(PetscCheckDebugger_Private("kdbg", string, &debugger)); 160 PetscCall(PetscCheckDebugger_Private("ups", string, &debugger)); 161 PetscCall(PetscCheckDebugger_Private("workshop", string, &debugger)); 162 PetscCall(PetscCheckDebugger_Private("pgdbg", string, &debugger)); 163 PetscCall(PetscCheckDebugger_Private("pathdb", string, &debugger)); 164 PetscCall(PetscCheckDebugger_Private("lldb", string, &debugger)); 165 PetscCall(PetscSetDebugger(debugger, useterminal)); 166 PetscFunctionReturn(0); 167 } 168 169 /*@ 170 PetscWaitOnError - If an error is detected and the process would normally exit the main program with `MPI_Abort()` sleep instead 171 of exiting. 172 173 Not Collective 174 175 Level: advanced 176 177 Note: 178 When -start_in_debugger -debugger_ranks x,y,z is used this prevents the processes NOT listed in x,y,z from calling MPI_Abort and 179 killing the user's debugging sessions. 180 181 .seealso: `PetscSetDebugger()`, `PetscAttachDebugger()` 182 @*/ 183 PetscErrorCode PetscWaitOnError() 184 { 185 petscwaitonerrorflg = PETSC_TRUE; 186 return 0; 187 } 188 189 /*@ 190 PetscAttachDebugger - Attaches the debugger to the running process. 191 192 Not Collective 193 194 Options Database Keys: 195 - -start_in_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] [-debugger_ranks m,n] -debug_terminal xterm or Terminal (for Apple) 196 . -on_error_attach_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] - Activates debugger attachment 197 198 Level: advanced 199 200 Developer Note: 201 Since this can be called by the error handler should it be calling `SETERRQ()` and `PetscCall()`? 202 203 .seealso: `PetscSetDebugger()`, `PetscSetDefaultDebugger()`, `PetscSetDebugTerminal()`, `PetscAttachDebuggerErrorHandler()`, `PetscStopForDebugger()` 204 @*/ 205 PetscErrorCode PetscAttachDebugger(void) 206 { 207 #if !defined(PETSC_CANNOT_START_DEBUGGER) && defined(PETSC_HAVE_FORK) 208 int child = 0; 209 PetscReal sleeptime = 0; 210 char program[PETSC_MAX_PATH_LEN], display[256], hostname[64]; 211 #endif 212 213 #if defined(PETSC_CANNOT_START_DEBUGGER) || !defined(PETSC_HAVE_FORK) 214 (*PetscErrorPrintf)("System cannot start debugger\n"); 215 (*PetscErrorPrintf)("On Cray run program in Totalview debugger\n"); 216 (*PetscErrorPrintf)("On Windows use Developer Studio(MSDEV)\n"); 217 PETSCABORT(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS); 218 #else 219 if (PetscUnlikely(PetscGetDisplay(display, sizeof(display)))) { 220 (*PetscErrorPrintf)("Cannot determine display\n"); 221 return PETSC_ERR_SYS; 222 } 223 if (PetscUnlikely(PetscGetProgramName(program, sizeof(program)))) { 224 (*PetscErrorPrintf)("Cannot determine program name needed to attach debugger\n"); 225 return PETSC_ERR_SYS; 226 } 227 if (PetscUnlikely(!program[0])) { 228 (*PetscErrorPrintf)("Cannot determine program name needed to attach debugger\n"); 229 return PETSC_ERR_SYS; 230 } 231 child = (int)fork(); 232 if (PetscUnlikely(child < 0)) { 233 (*PetscErrorPrintf)("Error in fork() prior to attaching debugger\n"); 234 return PETSC_ERR_SYS; 235 } 236 petscindebugger = PETSC_TRUE; 237 238 /* 239 Swap role the parent and child. This is (I think) so that control c typed 240 in the debugger goes to the correct process. 241 */ 242 #if !defined(PETSC_DO_NOT_SWAP_CHILD_FOR_DEBUGGER) 243 child = child ? 0 : (int)getppid(); 244 #endif 245 246 if (child) { /* I am the parent, will run the debugger */ 247 const char *args[10]; 248 char pid[10]; 249 PetscInt j, jj; 250 PetscBool isdbx, isidb, isxldb, isxxgdb, isups, isxdb, isworkshop, isddd, iskdbg, islldb; 251 252 PetscCall(PetscGetHostName(hostname, sizeof(hostname))); 253 /* 254 We need to send a continue signal to the "child" process on the 255 alpha, otherwise it just stays off forever 256 */ 257 #if defined(PETSC_NEED_KILL_FOR_DEBUGGER) 258 kill(child, SIGCONT); 259 #endif 260 sprintf(pid, "%d", child); 261 262 PetscCall(PetscStrcmp(PetscDebugger, "xxgdb", &isxxgdb)); 263 PetscCall(PetscStrcmp(PetscDebugger, "ddd", &isddd)); 264 PetscCall(PetscStrcmp(PetscDebugger, "kdbg", &iskdbg)); 265 PetscCall(PetscStrcmp(PetscDebugger, "ups", &isups)); 266 PetscCall(PetscStrcmp(PetscDebugger, "xldb", &isxldb)); 267 PetscCall(PetscStrcmp(PetscDebugger, "xdb", &isxdb)); 268 PetscCall(PetscStrcmp(PetscDebugger, "dbx", &isdbx)); 269 PetscCall(PetscStrcmp(PetscDebugger, "idb", &isidb)); 270 PetscCall(PetscStrcmp(PetscDebugger, "workshop", &isworkshop)); 271 PetscCall(PetscStrcmp(PetscDebugger, "lldb", &islldb)); 272 273 if (isxxgdb || isups || isddd) { 274 args[1] = program; 275 args[2] = pid; 276 args[3] = "-display"; 277 args[0] = PetscDebugger; 278 args[4] = display; 279 args[5] = NULL; 280 printf("PETSC: Attaching %s to %s %s on %s\n", args[0], args[1], pid, hostname); 281 if (execvp(args[0], (char **)args) < 0) { 282 perror("Unable to start debugger"); 283 exit(0); 284 } 285 } else if (iskdbg) { 286 args[1] = "-p"; 287 args[2] = pid; 288 args[3] = program; 289 args[4] = "-display"; 290 args[0] = PetscDebugger; 291 args[5] = display; 292 args[6] = NULL; 293 printf("PETSC: Attaching %s to %s %s on %s\n", args[0], args[3], pid, hostname); 294 if (execvp(args[0], (char **)args) < 0) { 295 perror("Unable to start debugger"); 296 exit(0); 297 } 298 } else if (isxldb) { 299 args[1] = "-a"; 300 args[2] = pid; 301 args[3] = program; 302 args[4] = "-display"; 303 args[0] = PetscDebugger; 304 args[5] = display; 305 args[6] = NULL; 306 printf("PETSC: Attaching %s to %s %s on %s\n", args[0], args[1], pid, hostname); 307 if (execvp(args[0], (char **)args) < 0) { 308 perror("Unable to start debugger"); 309 exit(0); 310 } 311 } else if (isworkshop) { 312 args[1] = "-s"; 313 args[2] = pid; 314 args[3] = "-D"; 315 args[4] = "-"; 316 args[0] = PetscDebugger; 317 args[5] = pid; 318 args[6] = "-display"; 319 args[7] = display; 320 args[8] = NULL; 321 printf("PETSC: Attaching %s to %s on %s\n", args[0], pid, hostname); 322 if (execvp(args[0], (char **)args) < 0) { 323 perror("Unable to start debugger"); 324 exit(0); 325 } 326 } else { 327 j = 0; 328 if (UseDebugTerminal) { 329 PetscBool cmp; 330 char *tmp, *tmp1; 331 PetscCall(PetscStrncmp(DebugTerminal, "Terminal", 8, &cmp)); 332 if (cmp) { 333 char command[1024]; 334 if (islldb) PetscCall(PetscSNPrintf(command, sizeof(command), "osascript -e 'tell app \"Terminal\" to do script \"lldb -p %s \"'\n", pid)); 335 else { 336 char fullprogram[PETSC_MAX_PATH_LEN]; 337 PetscCall(PetscGetFullPath(program, fullprogram, sizeof(fullprogram))); 338 PetscCall(PetscSNPrintf(command, sizeof(command), "osascript -e 'tell app \"Terminal\" to do script \"%s %s %s \"'\n", PetscDebugger, fullprogram, pid)); 339 } 340 PetscCall(PetscPOpen(PETSC_COMM_SELF, NULL, command, "r", NULL)); 341 exit(0); 342 } 343 344 PetscCall(PetscStrncmp(DebugTerminal, "screen", 6, &cmp)); 345 if (!cmp) PetscCall(PetscStrncmp(DebugTerminal, "gnome-terminal", 6, &cmp)); 346 if (cmp) display[0] = 0; /* when using screen, we never pass -display */ 347 args[j++] = tmp = DebugTerminal; 348 if (display[0]) { 349 args[j++] = "-display"; 350 args[j++] = display; 351 } 352 while (*tmp) { 353 PetscCall(PetscStrchr(tmp, ' ', &tmp1)); 354 if (!tmp1) break; 355 *tmp1 = 0; 356 tmp = tmp1 + 1; 357 args[j++] = tmp; 358 } 359 } 360 args[j++] = PetscDebugger; 361 jj = j; 362 /* this is for default gdb */ 363 args[j++] = program; 364 args[j++] = pid; 365 args[j++] = NULL; 366 367 if (isidb) { 368 j = jj; 369 args[j++] = "-pid"; 370 args[j++] = pid; 371 args[j++] = "-gdb"; 372 args[j++] = program; 373 args[j++] = NULL; 374 } 375 if (islldb) { 376 j = jj; 377 args[j++] = "-p"; 378 args[j++] = pid; 379 args[j++] = NULL; 380 } 381 if (isdbx) { 382 j = jj; 383 #if defined(PETSC_USE_P_FOR_DEBUGGER) 384 args[j++] = "-p"; 385 args[j++] = pid; 386 args[j++] = program; 387 #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER) 388 args[j++] = "-l"; 389 args[j++] = "ALL"; 390 args[j++] = "-P"; 391 args[j++] = pid; 392 args[j++] = program; 393 #elif defined(PETSC_USE_A_FOR_DEBUGGER) 394 args[j++] = "-a"; 395 args[j++] = pid; 396 #elif defined(PETSC_USE_PID_FOR_DEBUGGER) 397 args[j++] = "-pid"; 398 args[j++] = pid; 399 args[j++] = program; 400 #else 401 args[j++] = program; 402 args[j++] = pid; 403 #endif 404 args[j++] = NULL; 405 } 406 if (UseDebugTerminal) { 407 if (display[0]) printf("PETSC: Attaching %s to %s of pid %s on display %s on machine %s\n", PetscDebugger, program, pid, display, hostname); 408 else printf("PETSC: Attaching %s to %s on pid %s on %s\n", PetscDebugger, program, pid, hostname); 409 410 if (execvp(args[0], (char **)args) < 0) { 411 perror("Unable to start debugger in xterm"); 412 exit(0); 413 } 414 } else { 415 printf("PETSC: Attaching %s to %s of pid %s on %s\n", PetscDebugger, program, pid, hostname); 416 if (execvp(args[0], (char **)args) < 0) { 417 perror("Unable to start debugger"); 418 exit(0); 419 } 420 } 421 } 422 } else { /* I am the child, continue with user code */ 423 sleeptime = 10; /* default to sleep waiting for debugger */ 424 PetscCall(PetscOptionsGetReal(NULL, NULL, "-debugger_pause", &sleeptime, NULL)); 425 if (sleeptime < 0) sleeptime = -sleeptime; 426 #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP) 427 /* 428 HP cannot attach process to sleeping debugger, hence count instead 429 */ 430 { 431 PetscReal x = 1.0; 432 int i = 10000000; 433 while (i--) x++; /* cannot attach to sleeper */ 434 } 435 #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY) 436 /* 437 IBM sleep may return at anytime, hence must see if there is more time to sleep 438 */ 439 { 440 int left = sleeptime; 441 while (left > 0) left = PetscSleep(left) - 1; 442 } 443 #else 444 PetscSleep(sleeptime); 445 #endif 446 } 447 #endif 448 return 0; 449 } 450 451 /*@C 452 PetscAttachDebuggerErrorHandler - Error handler that attaches 453 a debugger to a running process when an error is detected. 454 This routine is useful for examining variables, etc. 455 456 Not Collective 457 458 Input Parameters: 459 + comm - communicator over which error occurred 460 . line - the line number of the error (indicated by __LINE__) 461 . file - the file in which the error was detected (indicated by __FILE__) 462 . message - an error text string, usually just printed to the screen 463 . number - the generic error number 464 . p - `PETSC_ERROR_INITIAL` if error just detected, otherwise `PETSC_ERROR_REPEAT` 465 - ctx - error handler context 466 467 Options Database Keys: 468 + -on_error_attach_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] - Activates debugger attachment 469 - -start_in_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] [-debugger_ranks m,n] 470 471 Level: developer 472 473 Notes: 474 By default the GNU debugger, gdb, is used. Alternatives are cuda-gdb, lldb, dbx and 475 xxgdb,xldb (on IBM rs6000), xdb (on HP-UX). 476 477 Most users need not directly employ this routine and the other error 478 handlers, but can instead use the simplified interface SETERR, which has 479 the calling sequence 480 $ SETERRQ(PETSC_COMM_SELF,number,p,message) 481 482 Notes for experienced users: 483 Use `PetscPushErrorHandler()` to set the desired error handler. The 484 currently available PETSc error handlers are 485 $ PetscTraceBackErrorHandler() 486 $ PetscAttachDebuggerErrorHandler() 487 $ PetscAbortErrorHandler() 488 or you may write your own. 489 490 Developer Note: 491 This routine calls abort instead of returning because if it returned then `MPI_Abort()` would get called which can generate an exception 492 causing the debugger to be attached again in a cycle. 493 494 .seealso: `PetscSetDebuggerFromString()`, `PetscSetDebugger()`, `PetscSetDefaultDebugger()`, `PetscError()`, `PetscPushErrorHandler()`, `PetscPopErrorHandler()`, `PetscTraceBackErrorHandler()`, 495 `PetscAbortErrorHandler()`, `PetscMPIAbortErrorHandler()`, `PetscEmacsClientErrorHandler()`, `PetscReturnErrorHandler()`, `PetscSetDebugTermainal()` 496 @*/ 497 PetscErrorCode PetscAttachDebuggerErrorHandler(MPI_Comm comm, int line, const char *fun, const char *file, PetscErrorCode num, PetscErrorType p, const char *mess, void *ctx) 498 { 499 if (!mess) mess = " "; 500 501 if (fun) (*PetscErrorPrintf)("%s() at %s:%d %s\n", fun, file, line, mess); 502 else (*PetscErrorPrintf)("%s:%d %s\n", file, line, mess); 503 504 PetscAttachDebugger(); 505 abort(); /* call abort because don't want to kill other MPI ranks that may successfully attach to debugger */ 506 PetscFunctionReturn(0); 507 } 508 509 /*@C 510 PetscStopForDebugger - Prints a message to the screen indicating how to 511 attach to the process with the debugger and then waits for the 512 debugger to attach. 513 514 Not Collective 515 516 Options Database Key: 517 . -stop_for_debugger - will stop for you to attach the debugger when PetscInitialize() is called 518 519 Level: developer 520 521 Note: 522 This is likely never needed since `PetscAttachDebugger()` is easier to use and seems to always work. 523 524 Developer Note: 525 Since this can be called by the error handler, should it be calling `SETERRQ()` and `PetscCall()`? 526 527 .seealso: `PetscSetDebugger()`, `PetscAttachDebugger()` 528 @*/ 529 PetscErrorCode PetscStopForDebugger(void) 530 { 531 PetscErrorCode ierr; 532 PetscInt sleeptime = 0; 533 #if !defined(PETSC_CANNOT_START_DEBUGGER) 534 int ppid; 535 PetscMPIInt rank; 536 char program[PETSC_MAX_PATH_LEN], hostname[256]; 537 PetscBool isdbx, isxldb, isxxgdb, isddd, iskdbg, isups, isxdb, islldb; 538 #endif 539 540 PetscFunctionBegin; 541 #if defined(PETSC_CANNOT_START_DEBUGGER) 542 (*PetscErrorPrintf)("System cannot start debugger; just continuing program\n"); 543 #else 544 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); 545 if (ierr) rank = 0; /* ignore error since this may be already in error handler */ 546 ierr = PetscGetHostName(hostname, sizeof(hostname)); 547 if (ierr) { 548 (*PetscErrorPrintf)("Cannot determine hostname; just continuing program\n"); 549 PetscFunctionReturn(0); 550 } 551 552 ierr = PetscGetProgramName(program, sizeof(program)); 553 if (ierr) { 554 (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n"); 555 PetscFunctionReturn(0); 556 } 557 if (!program[0]) { 558 (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n"); 559 PetscFunctionReturn(0); 560 } 561 562 ppid = getpid(); 563 564 PetscCall(PetscStrcmp(PetscDebugger, "xxgdb", &isxxgdb)); 565 PetscCall(PetscStrcmp(PetscDebugger, "ddd", &isddd)); 566 PetscCall(PetscStrcmp(PetscDebugger, "kdbg", &iskdbg)); 567 PetscCall(PetscStrcmp(PetscDebugger, "ups", &isups)); 568 PetscCall(PetscStrcmp(PetscDebugger, "xldb", &isxldb)); 569 PetscCall(PetscStrcmp(PetscDebugger, "xdb", &isxdb)); 570 PetscCall(PetscStrcmp(PetscDebugger, "dbx", &isdbx)); 571 PetscCall(PetscStrcmp(PetscDebugger, "lldb", &islldb)); 572 573 if (isxxgdb || isups || isddd || iskdbg) printf("[%d]%s>>%s %s %d\n", rank, hostname, PetscDebugger, program, ppid); 574 else if (isxldb) printf("[%d]%s>>%s -a %d %s\n", rank, hostname, PetscDebugger, ppid, program); 575 else if (islldb) printf("[%d]%s>>%s -p %d\n", rank, hostname, PetscDebugger, ppid); 576 else if (isdbx) { 577 #if defined(PETSC_USE_P_FOR_DEBUGGER) 578 printf("[%d]%s>>%s -p %d %s\n", rank, hostname, PetscDebugger, ppid, program); 579 #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER) 580 printf("[%d]%s>>%s -l ALL -P %d %s\n", rank, hostname, PetscDebugger, ppid, program); 581 #elif defined(PETSC_USE_A_FOR_DEBUGGER) 582 printf("[%d]%s>>%s -a %d\n", rank, hostname, PetscDebugger, ppid); 583 #elif defined(PETSC_USE_PID_FOR_DEBUGGER) 584 printf("[%d]%s>>%s -pid %d %s\n", rank, hostname, PetscDebugger, ppid, program); 585 #else 586 printf("[%d]%s>>%s %s %d\n", rank, hostname, PetscDebugger, program, ppid); 587 #endif 588 } 589 #endif /* PETSC_CANNOT_START_DEBUGGER */ 590 591 fflush(stdout); /* ignore error because may already be in error handler */ 592 593 sleeptime = 25; /* default to sleep waiting for debugger */ 594 PetscOptionsGetInt(NULL, NULL, "-debugger_pause", &sleeptime, NULL); /* ignore error because may already be in error handler */ 595 if (sleeptime < 0) sleeptime = -sleeptime; 596 #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP) 597 /* 598 HP cannot attach process to sleeping debugger, hence count instead 599 */ 600 { 601 PetscReal x = 1.0; 602 int i = 10000000; 603 while (i--) x++; /* cannot attach to sleeper */ 604 } 605 #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY) 606 /* 607 IBM sleep may return at anytime, hence must see if there is more time to sleep 608 */ 609 { 610 int left = sleeptime; 611 while (left > 0) left = sleep(left) - 1; 612 } 613 #else 614 PetscSleep(sleeptime); 615 #endif 616 PetscFunctionReturn(0); 617 } 618