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 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 #if defined(PETSC_CANNOT_START_DEBUGGER) || !defined(PETSC_HAVE_FORK) 207 (*PetscErrorPrintf)("System cannot start debugger\n"); 208 (*PetscErrorPrintf)("On Cray run program in Totalview debugger\n"); 209 (*PetscErrorPrintf)("On Windows use Developer Studio(MSDEV)\n"); 210 PETSCABORT(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS); 211 #else 212 if (PetscUnlikely(PetscGetDisplay(display, sizeof(display)))) { 213 (*PetscErrorPrintf)("Cannot determine display\n"); 214 return PETSC_ERR_SYS; 215 } 216 if (PetscUnlikely(PetscGetProgramName(program, sizeof(program)))) { 217 (*PetscErrorPrintf)("Cannot determine program name needed to attach debugger\n"); 218 return PETSC_ERR_SYS; 219 } 220 if (PetscUnlikely(!program[0])) { 221 (*PetscErrorPrintf)("Cannot determine program name needed to attach debugger\n"); 222 return PETSC_ERR_SYS; 223 } 224 child = (int)fork(); 225 if (PetscUnlikely(child < 0)) { 226 (*PetscErrorPrintf)("Error in fork() prior to attaching debugger\n"); 227 return PETSC_ERR_SYS; 228 } 229 petscindebugger = PETSC_TRUE; 230 231 /* 232 Swap role the parent and child. This is (I think) so that control c typed 233 in the debugger goes to the correct process. 234 */ 235 #if !defined(PETSC_DO_NOT_SWAP_CHILD_FOR_DEBUGGER) 236 child = child ? 0 : (int)getppid(); 237 #endif 238 239 if (child) { /* I am the parent, will run the debugger */ 240 const char *args[10]; 241 char pid[10]; 242 PetscInt j, jj; 243 PetscBool isdbx, isidb, isxldb, isxxgdb, isups, isxdb, isworkshop, isddd, iskdbg, islldb; 244 245 PetscCall(PetscGetHostName(hostname, sizeof(hostname))); 246 /* 247 We need to send a continue signal to the "child" process on the 248 alpha, otherwise it just stays off forever 249 */ 250 #if defined(PETSC_NEED_KILL_FOR_DEBUGGER) 251 kill(child, SIGCONT); 252 #endif 253 sprintf(pid, "%d", child); 254 255 PetscCall(PetscStrcmp(PetscDebugger, "xxgdb", &isxxgdb)); 256 PetscCall(PetscStrcmp(PetscDebugger, "ddd", &isddd)); 257 PetscCall(PetscStrcmp(PetscDebugger, "kdbg", &iskdbg)); 258 PetscCall(PetscStrcmp(PetscDebugger, "ups", &isups)); 259 PetscCall(PetscStrcmp(PetscDebugger, "xldb", &isxldb)); 260 PetscCall(PetscStrcmp(PetscDebugger, "xdb", &isxdb)); 261 PetscCall(PetscStrcmp(PetscDebugger, "dbx", &isdbx)); 262 PetscCall(PetscStrcmp(PetscDebugger, "idb", &isidb)); 263 PetscCall(PetscStrcmp(PetscDebugger, "workshop", &isworkshop)); 264 PetscCall(PetscStrcmp(PetscDebugger, "lldb", &islldb)); 265 266 if (isxxgdb || isups || isddd) { 267 args[1] = program; 268 args[2] = pid; 269 args[3] = "-display"; 270 args[0] = PetscDebugger; 271 args[4] = display; 272 args[5] = NULL; 273 printf("PETSC: Attaching %s to %s %s on %s\n", args[0], args[1], pid, hostname); 274 if (execvp(args[0], (char **)args) < 0) { 275 perror("Unable to start debugger"); 276 exit(0); 277 } 278 } else if (iskdbg) { 279 args[1] = "-p"; 280 args[2] = pid; 281 args[3] = program; 282 args[4] = "-display"; 283 args[0] = PetscDebugger; 284 args[5] = display; 285 args[6] = NULL; 286 printf("PETSC: Attaching %s to %s %s on %s\n", args[0], args[3], pid, hostname); 287 if (execvp(args[0], (char **)args) < 0) { 288 perror("Unable to start debugger"); 289 exit(0); 290 } 291 } else if (isxldb) { 292 args[1] = "-a"; 293 args[2] = pid; 294 args[3] = program; 295 args[4] = "-display"; 296 args[0] = PetscDebugger; 297 args[5] = display; 298 args[6] = NULL; 299 printf("PETSC: Attaching %s to %s %s on %s\n", args[0], args[1], pid, hostname); 300 if (execvp(args[0], (char **)args) < 0) { 301 perror("Unable to start debugger"); 302 exit(0); 303 } 304 } else if (isworkshop) { 305 args[1] = "-s"; 306 args[2] = pid; 307 args[3] = "-D"; 308 args[4] = "-"; 309 args[0] = PetscDebugger; 310 args[5] = pid; 311 args[6] = "-display"; 312 args[7] = display; 313 args[8] = NULL; 314 printf("PETSC: Attaching %s to %s on %s\n", args[0], pid, hostname); 315 if (execvp(args[0], (char **)args) < 0) { 316 perror("Unable to start debugger"); 317 exit(0); 318 } 319 } else { 320 j = 0; 321 if (UseDebugTerminal) { 322 PetscBool cmp; 323 char *tmp, *tmp1; 324 PetscCall(PetscStrncmp(DebugTerminal, "Terminal", 8, &cmp)); 325 if (cmp) { 326 char command[1024]; 327 if (islldb) PetscCall(PetscSNPrintf(command, sizeof(command), "osascript -e 'tell app \"Terminal\" to do script \"lldb -p %s \"'\n", pid)); 328 else { 329 char fullprogram[PETSC_MAX_PATH_LEN]; 330 PetscCall(PetscGetFullPath(program, fullprogram, sizeof(fullprogram))); 331 PetscCall(PetscSNPrintf(command, sizeof(command), "osascript -e 'tell app \"Terminal\" to do script \"%s %s %s \"'\n", PetscDebugger, fullprogram, pid)); 332 } 333 PetscCall(PetscPOpen(PETSC_COMM_SELF, NULL, command, "r", NULL)); 334 exit(0); 335 } 336 337 PetscCall(PetscStrncmp(DebugTerminal, "screen", 6, &cmp)); 338 if (!cmp) PetscCall(PetscStrncmp(DebugTerminal, "gnome-terminal", 6, &cmp)); 339 if (cmp) display[0] = 0; /* when using screen, we never pass -display */ 340 args[j++] = tmp = DebugTerminal; 341 if (display[0]) { 342 args[j++] = "-display"; 343 args[j++] = display; 344 } 345 while (*tmp) { 346 PetscCall(PetscStrchr(tmp, ' ', &tmp1)); 347 if (!tmp1) break; 348 *tmp1 = 0; 349 tmp = tmp1 + 1; 350 args[j++] = tmp; 351 } 352 } 353 args[j++] = PetscDebugger; 354 jj = j; 355 /* this is for default gdb */ 356 args[j++] = program; 357 args[j++] = pid; 358 args[j++] = NULL; 359 360 if (isidb) { 361 j = jj; 362 args[j++] = "-pid"; 363 args[j++] = pid; 364 args[j++] = "-gdb"; 365 args[j++] = program; 366 args[j++] = NULL; 367 } 368 if (islldb) { 369 j = jj; 370 args[j++] = "-p"; 371 args[j++] = pid; 372 args[j++] = NULL; 373 } 374 if (isdbx) { 375 j = jj; 376 #if defined(PETSC_USE_P_FOR_DEBUGGER) 377 args[j++] = "-p"; 378 args[j++] = pid; 379 args[j++] = program; 380 #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER) 381 args[j++] = "-l"; 382 args[j++] = "ALL"; 383 args[j++] = "-P"; 384 args[j++] = pid; 385 args[j++] = program; 386 #elif defined(PETSC_USE_A_FOR_DEBUGGER) 387 args[j++] = "-a"; 388 args[j++] = pid; 389 #elif defined(PETSC_USE_PID_FOR_DEBUGGER) 390 args[j++] = "-pid"; 391 args[j++] = pid; 392 args[j++] = program; 393 #else 394 args[j++] = program; 395 args[j++] = pid; 396 #endif 397 args[j++] = NULL; 398 } 399 if (UseDebugTerminal) { 400 if (display[0]) printf("PETSC: Attaching %s to %s of pid %s on display %s on machine %s\n", PetscDebugger, program, pid, display, hostname); 401 else printf("PETSC: Attaching %s to %s on pid %s on %s\n", PetscDebugger, program, pid, hostname); 402 403 if (execvp(args[0], (char **)args) < 0) { 404 perror("Unable to start debugger in xterm"); 405 exit(0); 406 } 407 } else { 408 printf("PETSC: Attaching %s to %s of pid %s on %s\n", PetscDebugger, program, pid, hostname); 409 if (execvp(args[0], (char **)args) < 0) { 410 perror("Unable to start debugger"); 411 exit(0); 412 } 413 } 414 } 415 } else { /* I am the child, continue with user code */ 416 sleeptime = 10; /* default to sleep waiting for debugger */ 417 PetscCall(PetscOptionsGetReal(NULL, NULL, "-debugger_pause", &sleeptime, NULL)); 418 if (sleeptime < 0) sleeptime = -sleeptime; 419 #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP) 420 /* 421 HP cannot attach process to sleeping debugger, hence count instead 422 */ 423 { 424 PetscReal x = 1.0; 425 int i = 10000000; 426 while (i--) x++; /* cannot attach to sleeper */ 427 } 428 #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY) 429 /* 430 IBM sleep may return at anytime, hence must see if there is more time to sleep 431 */ 432 { 433 int left = sleeptime; 434 while (left > 0) left = PetscSleep(left) - 1; 435 } 436 #else 437 PetscSleep(sleeptime); 438 #endif 439 } 440 #endif 441 return 0; 442 } 443 444 /*@C 445 PetscAttachDebuggerErrorHandler - Error handler that attaches 446 a debugger to a running process when an error is detected. 447 This routine is useful for examining variables, etc. 448 449 Not Collective 450 451 Input Parameters: 452 + comm - communicator over which error occurred 453 . line - the line number of the error (indicated by __LINE__) 454 . file - the file in which the error was detected (indicated by __FILE__) 455 . message - an error text string, usually just printed to the screen 456 . number - the generic error number 457 . p - PETSC_ERROR_INITIAL if error just detected, otherwise PETSC_ERROR_REPEAT 458 - ctx - error handler context 459 460 Options Database Keys: 461 + -on_error_attach_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] - Activates debugger attachment 462 - -start_in_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] [-debugger_ranks m,n] 463 464 Level: developer 465 466 Notes: 467 By default the GNU debugger, gdb, is used. Alternatives are cuda-gdb, lldb, dbx and 468 xxgdb,xldb (on IBM rs6000), xdb (on HP-UX). 469 470 Most users need not directly employ this routine and the other error 471 handlers, but can instead use the simplified interface SETERR, which has 472 the calling sequence 473 $ SETERRQ(PETSC_COMM_SELF,number,p,message) 474 475 Notes for experienced users: 476 Use PetscPushErrorHandler() to set the desired error handler. The 477 currently available PETSc error handlers are 478 $ PetscTraceBackErrorHandler() 479 $ PetscAttachDebuggerErrorHandler() 480 $ PetscAbortErrorHandler() 481 or you may write your own. 482 483 Developer Notes: 484 This routine calls abort instead of returning because if it returned then MPI_Abort() would get called which can generate an exception 485 causing the debugger to be attached again in a cycle. 486 487 .seealso: `PetscSetDebuggerFromString()`, `PetscSetDebugger()`, `PetscSetDefaultDebugger()`, `PetscError()`, `PetscPushErrorHandler()`, `PetscPopErrorHandler()`, `PetscTraceBackErrorHandler()`, 488 `PetscAbortErrorHandler()`, `PetscMPIAbortErrorHandler()`, `PetscEmacsClientErrorHandler()`, `PetscReturnErrorHandler()`, `PetscSetDebugTermainal()` 489 @*/ 490 PetscErrorCode PetscAttachDebuggerErrorHandler(MPI_Comm comm, int line, const char *fun, const char *file, PetscErrorCode num, PetscErrorType p, const char *mess, void *ctx) { 491 if (!mess) mess = " "; 492 493 if (fun) (*PetscErrorPrintf)("%s() at %s:%d %s\n", fun, file, line, mess); 494 else (*PetscErrorPrintf)("%s:%d %s\n", file, line, mess); 495 496 PetscAttachDebugger(); 497 abort(); /* call abort because don't want to kill other MPI processes that may successfully attach to debugger */ 498 return 0; 499 } 500 501 /*@C 502 PetscStopForDebugger - Prints a message to the screen indicating how to 503 attach to the process with the debugger and then waits for the 504 debugger to attach. 505 506 Not Collective 507 508 Options Database: 509 . -stop_for_debugger - will stop for you to attach the debugger when PetscInitialize() is called 510 511 Level: developer 512 513 Notes: 514 This is likely never needed since PetscAttachDebugger() is easier to use and seems to always work. 515 516 Developer Notes: 517 Since this can be called by the error handler, should it be calling SETERRQ() and PetscCall()? 518 519 .seealso: `PetscSetDebugger()`, `PetscAttachDebugger()` 520 @*/ 521 PetscErrorCode PetscStopForDebugger(void) { 522 PetscErrorCode ierr; 523 PetscInt sleeptime = 0; 524 #if !defined(PETSC_CANNOT_START_DEBUGGER) 525 int ppid; 526 PetscMPIInt rank; 527 char program[PETSC_MAX_PATH_LEN], hostname[256]; 528 PetscBool isdbx, isxldb, isxxgdb, isddd, iskdbg, isups, isxdb, islldb; 529 #endif 530 531 PetscFunctionBegin; 532 #if defined(PETSC_CANNOT_START_DEBUGGER) 533 (*PetscErrorPrintf)("System cannot start debugger; just continuing program\n"); 534 #else 535 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); 536 if (ierr) rank = 0; /* ignore error since this may be already in error handler */ 537 ierr = PetscGetHostName(hostname, sizeof(hostname)); 538 if (ierr) { 539 (*PetscErrorPrintf)("Cannot determine hostname; just continuing program\n"); 540 PetscFunctionReturn(0); 541 } 542 543 ierr = PetscGetProgramName(program, sizeof(program)); 544 if (ierr) { 545 (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n"); 546 PetscFunctionReturn(0); 547 } 548 if (!program[0]) { 549 (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n"); 550 PetscFunctionReturn(0); 551 } 552 553 ppid = getpid(); 554 555 PetscCall(PetscStrcmp(PetscDebugger, "xxgdb", &isxxgdb)); 556 PetscCall(PetscStrcmp(PetscDebugger, "ddd", &isddd)); 557 PetscCall(PetscStrcmp(PetscDebugger, "kdbg", &iskdbg)); 558 PetscCall(PetscStrcmp(PetscDebugger, "ups", &isups)); 559 PetscCall(PetscStrcmp(PetscDebugger, "xldb", &isxldb)); 560 PetscCall(PetscStrcmp(PetscDebugger, "xdb", &isxdb)); 561 PetscCall(PetscStrcmp(PetscDebugger, "dbx", &isdbx)); 562 PetscCall(PetscStrcmp(PetscDebugger, "lldb", &islldb)); 563 564 if (isxxgdb || isups || isddd || iskdbg) printf("[%d]%s>>%s %s %d\n", rank, hostname, PetscDebugger, program, ppid); 565 else if (isxldb) printf("[%d]%s>>%s -a %d %s\n", rank, hostname, PetscDebugger, ppid, program); 566 else if (islldb) printf("[%d]%s>>%s -p %d\n", rank, hostname, PetscDebugger, ppid); 567 else if (isdbx) { 568 #if defined(PETSC_USE_P_FOR_DEBUGGER) 569 printf("[%d]%s>>%s -p %d %s\n", rank, hostname, PetscDebugger, ppid, program); 570 #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER) 571 printf("[%d]%s>>%s -l ALL -P %d %s\n", rank, hostname, PetscDebugger, ppid, program); 572 #elif defined(PETSC_USE_A_FOR_DEBUGGER) 573 printf("[%d]%s>>%s -a %d\n", rank, hostname, PetscDebugger, ppid); 574 #elif defined(PETSC_USE_PID_FOR_DEBUGGER) 575 printf("[%d]%s>>%s -pid %d %s\n", rank, hostname, PetscDebugger, ppid, program); 576 #else 577 printf("[%d]%s>>%s %s %d\n", rank, hostname, PetscDebugger, program, ppid); 578 #endif 579 } 580 #endif /* PETSC_CANNOT_START_DEBUGGER */ 581 582 fflush(stdout); /* ignore error because may already be in error handler */ 583 584 sleeptime = 25; /* default to sleep waiting for debugger */ 585 PetscOptionsGetInt(NULL, NULL, "-debugger_pause", &sleeptime, NULL); /* ignore error because may already be in error handler */ 586 if (sleeptime < 0) sleeptime = -sleeptime; 587 #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP) 588 /* 589 HP cannot attach process to sleeping debugger, hence count instead 590 */ 591 { 592 PetscReal x = 1.0; 593 int i = 10000000; 594 while (i--) x++; /* cannot attach to sleeper */ 595 } 596 #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY) 597 /* 598 IBM sleep may return at anytime, hence must see if there is more time to sleep 599 */ 600 { 601 int left = sleeptime; 602 while (left > 0) left = sleep(left) - 1; 603 } 604 #else 605 PetscSleep(sleeptime); 606 #endif 607 PetscFunctionReturn(0); 608 } 609