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