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