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