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