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 Parameters: 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 Keys: 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 PetscBool xterm; 51 52 PetscFunctionBegin; 53 PetscCall(PetscStrncpy(DebugTerminal, terminal, sizeof(DebugTerminal))); 54 PetscCall(PetscStrcmp(terminal, "xterm", &xterm)); 55 if (xterm) PetscCall(PetscStrlcat(DebugTerminal, " -e", sizeof(DebugTerminal))); 56 PetscFunctionReturn(0); 57 } 58 59 /*@C 60 PetscSetDebugger - Sets options associated with the debugger. 61 62 Not Collective 63 64 Input Parameters: 65 + debugger - name of debugger, which should be in your path, 66 usually "lldb", "dbx", "gdb", "cuda-gdb", "idb", "xxgdb", "kdgb" or "ddd". Also, HP-UX 67 supports "xdb", and IBM rs6000 supports "xldb". 68 69 - usedebugterminal - flag to indicate debugger window, set to either PETSC_TRUE (to indicate 70 debugger should be started in a new terminal window) or PETSC_FALSE (to start debugger 71 in initial window (the option PETSC_FALSE makes no sense when using more 72 than one MPI process.) 73 74 Level: developer 75 76 Fortran Note: 77 This routine is not supported in Fortran. 78 79 .seealso: `PetscAttachDebugger()`, `PetscAttachDebuggerErrorHandler()`, `PetscSetDebugTerminal()` 80 @*/ 81 PetscErrorCode PetscSetDebugger(const char debugger[], PetscBool usedebugterminal) { 82 PetscFunctionBegin; 83 if (debugger) PetscCall(PetscStrncpy(PetscDebugger, debugger, sizeof(PetscDebugger))); 84 if (UseDebugTerminal) UseDebugTerminal = usedebugterminal; 85 PetscFunctionReturn(0); 86 } 87 88 /*@C 89 PetscSetDefaultDebugger - Causes PETSc to use its default debugger and output terminal 90 91 Not collective 92 93 Level: developer 94 95 .seealso: `PetscSetDebugger()`, `PetscSetDebuggerFromString()` 96 @*/ 97 PetscErrorCode PetscSetDefaultDebugger(void) { 98 PetscFunctionBegin; 99 #if defined(PETSC_USE_DEBUGGER) 100 PetscCall(PetscSetDebugger(PETSC_USE_DEBUGGER, PETSC_TRUE)); 101 #endif 102 #if defined(__APPLE__) 103 PetscCall(PetscSetDebugTerminal("Terminal")); 104 #else 105 PetscCall(PetscSetDebugTerminal("xterm")); 106 #endif 107 PetscFunctionReturn(0); 108 } 109 110 static PetscErrorCode PetscCheckDebugger_Private(const char defaultDbg[], const char string[], const char *debugger[]) { 111 PetscBool exists; 112 char *f; 113 114 PetscFunctionBegin; 115 PetscCall(PetscStrstr(string, defaultDbg, &f)); 116 if (f) { 117 PetscCall(PetscTestFile(string, 'x', &exists)); 118 if (exists) *debugger = string; 119 else *debugger = defaultDbg; 120 } 121 PetscFunctionReturn(0); 122 } 123 124 /*@C 125 PetscSetDebuggerFromString - Set the complete path for the 126 debugger for PETSc to use. 127 128 Not collective 129 130 Level: developer 131 132 .seealso: `PetscSetDebugger()`, `PetscSetDefaultDebugger()` 133 @*/ 134 PetscErrorCode PetscSetDebuggerFromString(const char *string) { 135 const char *debugger = NULL; 136 PetscBool useterminal = PETSC_TRUE; 137 char *f; 138 139 PetscFunctionBegin; 140 PetscCall(PetscStrstr(string, "noxterm", &f)); 141 if (f) useterminal = PETSC_FALSE; 142 PetscCall(PetscStrstr(string, "ddd", &f)); 143 if (f) useterminal = PETSC_FALSE; 144 PetscCall(PetscStrstr(string, "noterminal", &f)); 145 if (f) useterminal = PETSC_FALSE; 146 PetscCall(PetscCheckDebugger_Private("xdb", string, &debugger)); 147 PetscCall(PetscCheckDebugger_Private("dbx", string, &debugger)); 148 PetscCall(PetscCheckDebugger_Private("xldb", string, &debugger)); 149 PetscCall(PetscCheckDebugger_Private("gdb", string, &debugger)); 150 PetscCall(PetscCheckDebugger_Private("cuda-gdb", string, &debugger)); 151 PetscCall(PetscCheckDebugger_Private("idb", string, &debugger)); 152 PetscCall(PetscCheckDebugger_Private("xxgdb", string, &debugger)); 153 PetscCall(PetscCheckDebugger_Private("ddd", string, &debugger)); 154 PetscCall(PetscCheckDebugger_Private("kdbg", string, &debugger)); 155 PetscCall(PetscCheckDebugger_Private("ups", string, &debugger)); 156 PetscCall(PetscCheckDebugger_Private("workshop", string, &debugger)); 157 PetscCall(PetscCheckDebugger_Private("pgdbg", string, &debugger)); 158 PetscCall(PetscCheckDebugger_Private("pathdb", string, &debugger)); 159 PetscCall(PetscCheckDebugger_Private("lldb", string, &debugger)); 160 PetscCall(PetscSetDebugger(debugger, useterminal)); 161 PetscFunctionReturn(0); 162 } 163 164 /*@ 165 PetscWaitOnError - If an error is detected and the process would normally exit the main program with MPI_Abort() sleep instead 166 of exiting. 167 168 Not Collective 169 170 Level: advanced 171 172 Notes: 173 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 174 killing the user's debugging sessions. 175 176 .seealso: `PetscSetDebugger()`, `PetscAttachDebugger()` 177 @*/ 178 PetscErrorCode PetscWaitOnError() { 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 Notes: 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 #if !defined(PETSC_CANNOT_START_DEBUGGER) && defined(PETSC_HAVE_FORK) 201 int child = 0; 202 PetscReal sleeptime = 0; 203 char program[PETSC_MAX_PATH_LEN], display[256], hostname[64]; 204 #endif 205 206 PetscFunctionBegin; 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 PetscFunctionReturn(PETSC_ERR_SYS); 216 } 217 if (PetscUnlikely(PetscGetProgramName(program, sizeof(program)))) { 218 (*PetscErrorPrintf)("Cannot determine program name\n"); 219 PetscFunctionReturn(PETSC_ERR_SYS); 220 } 221 if (PetscUnlikely(!program[0])) { 222 (*PetscErrorPrintf)("Cannot determine program name\n"); 223 PetscFunctionReturn(PETSC_ERR_SYS); 224 } 225 child = (int)fork(); 226 if (PetscUnlikely(child < 0)) { 227 (*PetscErrorPrintf)("Error in fork() prior to attaching debugger\n"); 228 PetscFunctionReturn(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 PetscFunctionReturn(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 Notes: 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 PetscFunctionBegin; 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 processes 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: 511 . -stop_for_debugger - will stop for you to attach the debugger when PetscInitialize() is called 512 513 Level: developer 514 515 Notes: 516 This is likely never needed since PetscAttachDebugger() is easier to use and seems to always work. 517 518 Developer Notes: 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 PetscErrorCode ierr; 525 PetscInt sleeptime = 0; 526 #if !defined(PETSC_CANNOT_START_DEBUGGER) 527 int ppid; 528 PetscMPIInt rank; 529 char program[PETSC_MAX_PATH_LEN], hostname[256]; 530 PetscBool isdbx, isxldb, isxxgdb, isddd, iskdbg, isups, isxdb, islldb; 531 #endif 532 533 PetscFunctionBegin; 534 #if defined(PETSC_CANNOT_START_DEBUGGER) 535 (*PetscErrorPrintf)("System cannot start debugger; just continuing program\n"); 536 #else 537 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); 538 if (ierr) rank = 0; /* ignore error since this may be already in error handler */ 539 ierr = PetscGetHostName(hostname, sizeof(hostname)); 540 if (ierr) { 541 (*PetscErrorPrintf)("Cannot determine hostname; just continuing program\n"); 542 PetscFunctionReturn(0); 543 } 544 545 ierr = PetscGetProgramName(program, sizeof(program)); 546 if (ierr) { 547 (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n"); 548 PetscFunctionReturn(0); 549 } 550 if (!program[0]) { 551 (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n"); 552 PetscFunctionReturn(0); 553 } 554 555 ppid = getpid(); 556 557 PetscCall(PetscStrcmp(PetscDebugger, "xxgdb", &isxxgdb)); 558 PetscCall(PetscStrcmp(PetscDebugger, "ddd", &isddd)); 559 PetscCall(PetscStrcmp(PetscDebugger, "kdbg", &iskdbg)); 560 PetscCall(PetscStrcmp(PetscDebugger, "ups", &isups)); 561 PetscCall(PetscStrcmp(PetscDebugger, "xldb", &isxldb)); 562 PetscCall(PetscStrcmp(PetscDebugger, "xdb", &isxdb)); 563 PetscCall(PetscStrcmp(PetscDebugger, "dbx", &isdbx)); 564 PetscCall(PetscStrcmp(PetscDebugger, "lldb", &islldb)); 565 566 if (isxxgdb || isups || isddd || iskdbg) printf("[%d]%s>>%s %s %d\n", rank, hostname, PetscDebugger, program, ppid); 567 else if (isxldb) printf("[%d]%s>>%s -a %d %s\n", rank, hostname, PetscDebugger, ppid, program); 568 else if (islldb) printf("[%d]%s>>%s -p %d\n", rank, hostname, PetscDebugger, ppid); 569 else if (isdbx) { 570 #if defined(PETSC_USE_P_FOR_DEBUGGER) 571 printf("[%d]%s>>%s -p %d %s\n", rank, hostname, PetscDebugger, ppid, program); 572 #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER) 573 printf("[%d]%s>>%s -l ALL -P %d %s\n", rank, hostname, PetscDebugger, ppid, program); 574 #elif defined(PETSC_USE_A_FOR_DEBUGGER) 575 printf("[%d]%s>>%s -a %d\n", rank, hostname, PetscDebugger, ppid); 576 #elif defined(PETSC_USE_PID_FOR_DEBUGGER) 577 printf("[%d]%s>>%s -pid %d %s\n", rank, hostname, PetscDebugger, ppid, program); 578 #else 579 printf("[%d]%s>>%s %s %d\n", rank, hostname, PetscDebugger, program, ppid); 580 #endif 581 } 582 #endif /* PETSC_CANNOT_START_DEBUGGER */ 583 584 fflush(stdout); /* ignore error because may already be in error handler */ 585 586 sleeptime = 25; /* default to sleep waiting for debugger */ 587 PetscOptionsGetInt(NULL, NULL, "-debugger_pause", &sleeptime, NULL); /* ignore error because may already be in error handler */ 588 if (sleeptime < 0) sleeptime = -sleeptime; 589 #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP) 590 /* 591 HP cannot attach process to sleeping debugger, hence count instead 592 */ 593 { 594 PetscReal x = 1.0; 595 int i = 10000000; 596 while (i--) x++; /* cannot attach to sleeper */ 597 } 598 #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY) 599 /* 600 IBM sleep may return at anytime, hence must see if there is more time to sleep 601 */ 602 { 603 int left = sleeptime; 604 while (left > 0) left = sleep(left) - 1; 605 } 606 #else 607 PetscSleep(sleeptime); 608 #endif 609 PetscFunctionReturn(0); 610 } 611