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 Xterm = PETSC_TRUE; 17 18 #undef __FUNCT__ 19 #define __FUNCT__ "PetscSetDebugTerminal" 20 /*@C 21 PetscSetDebugTerminal - Sets the terminal to use (instead of xterm) 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 -e", "urxvt -e". 28 29 Options Database Keys: 30 -debug_terminal terminal - use this terminal instead of xterm 31 32 Level: developer 33 34 Notes: 35 You can start the debugger for all processes in the same GNU screen session. 36 37 mpirun -n 4 ./myapp -start_in_debugger -debug_terminal "screen -X -S debug screen" 38 39 will open 4 windows in the session named "debug". 40 41 Fortran Note: 42 This routine is not supported in Fortran. 43 44 Concepts: debugger^setting 45 46 .seealso: PetscSetDebugger() 47 @*/ 48 PetscErrorCode PetscSetDebugTerminal(const char terminal[]) 49 { 50 PetscErrorCode ierr; 51 52 PetscFunctionBegin; 53 ierr = PetscStrcpy(DebugTerminal,terminal);CHKERRQ(ierr); 54 PetscFunctionReturn(0); 55 } 56 57 #undef __FUNCT__ 58 #define __FUNCT__ "PetscSetDebugger" 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", "idb", "xxgdb", "kdgb" or "ddd". Also, HP-UX 67 supports "xdb", and IBM rs6000 supports "xldb". 68 69 - xterm - flag to indicate debugger window, set to either PETSC_TRUE (to indicate 70 debugger should be started in a new xterm) 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 Concepts: debugger^setting 80 81 .seealso: PetscAttachDebugger(), PetscAttachDebuggerErrorHandler() 82 @*/ 83 PetscErrorCode PetscSetDebugger(const char debugger[],PetscBool xterm) 84 { 85 PetscErrorCode ierr; 86 87 PetscFunctionBegin; 88 if (debugger) { 89 ierr = PetscStrcpy(PetscDebugger,debugger);CHKERRQ(ierr); 90 } 91 Xterm = xterm; 92 PetscFunctionReturn(0); 93 } 94 95 #undef __FUNCT__ 96 #define __FUNCT__ "PetscSetDefaultDebugger" 97 /*@C 98 PetscSetDefaultDebugger - Causes PETSc to use its default debugger. 99 100 Not collective 101 102 Level: developer 103 104 .seealso: PetscSetDebugger(), PetscSetDebuggerFromString() 105 @*/ 106 PetscErrorCode PetscSetDefaultDebugger(void) 107 { 108 PetscErrorCode ierr; 109 110 PetscFunctionBegin; 111 #if defined(PETSC_USE_LLDB_DEBUGGER) 112 ierr = PetscSetDebugger("lldb",PETSC_TRUE);CHKERRQ(ierr); 113 #elif defined(PETSC_USE_DBX_DEBUGGER) 114 ierr = PetscSetDebugger("dbx",PETSC_TRUE);CHKERRQ(ierr); 115 #elif defined(PETSC_USE_XDB_DEBUGGER) 116 ierr = PetscSetDebugger("xdb",PETSC_TRUE);CHKERRQ(ierr); 117 #elif defined(PETSC_USE_IDB_DEBUGGER) 118 ierr = PetscSetDebugger("idb",PETSC_TRUE);CHKERRQ(ierr); 119 #else /* Default is gdb */ 120 ierr = PetscSetDebugger("gdb",PETSC_TRUE);CHKERRQ(ierr); 121 #endif 122 ierr = PetscSetDebugTerminal("xterm -e");CHKERRQ(ierr); 123 PetscFunctionReturn(0); 124 } 125 126 #undef __FUNCT__ 127 #define __FUNCT__ "PetscCheckDebugger_Private" 128 static PetscErrorCode PetscCheckDebugger_Private(const char defaultDbg[], const char string[], const char *debugger[]) 129 { 130 PetscBool exists; 131 char *f; 132 PetscErrorCode ierr; 133 134 PetscFunctionBegin; 135 ierr = PetscStrstr(string, defaultDbg, &f);CHKERRQ(ierr); 136 if (f) { 137 ierr = PetscTestFile(string, 'x', &exists);CHKERRQ(ierr); 138 if (exists) *debugger = string; 139 else *debugger = defaultDbg; 140 } 141 PetscFunctionReturn(0); 142 } 143 144 #undef __FUNCT__ 145 #define __FUNCT__ "PetscSetDebuggerFromString" 146 /*@C 147 PetscSetDebuggerFromString - Set the complete path for the 148 debugger for PETSc to use. 149 150 Not collective 151 152 Level: developer 153 154 .seealso: PetscSetDebugger(), PetscSetDefaultDebugger() 155 @*/ 156 PetscErrorCode PetscSetDebuggerFromString(const char *string) 157 { 158 const char *debugger = NULL; 159 PetscBool xterm = PETSC_TRUE; 160 char *f; 161 PetscErrorCode ierr; 162 163 PetscFunctionBegin; 164 ierr = PetscStrstr(string, "noxterm", &f);CHKERRQ(ierr); 165 if (f) xterm = PETSC_FALSE; 166 ierr = PetscStrstr(string, "ddd", &f);CHKERRQ(ierr); 167 if (f) xterm = PETSC_FALSE; 168 ierr = PetscCheckDebugger_Private("xdb", string, &debugger);CHKERRQ(ierr); 169 ierr = PetscCheckDebugger_Private("dbx", string, &debugger);CHKERRQ(ierr); 170 ierr = PetscCheckDebugger_Private("xldb", string, &debugger);CHKERRQ(ierr); 171 ierr = PetscCheckDebugger_Private("gdb", string, &debugger);CHKERRQ(ierr); 172 ierr = PetscCheckDebugger_Private("idb", string, &debugger);CHKERRQ(ierr); 173 ierr = PetscCheckDebugger_Private("xxgdb", string, &debugger);CHKERRQ(ierr); 174 ierr = PetscCheckDebugger_Private("ddd", string, &debugger);CHKERRQ(ierr); 175 ierr = PetscCheckDebugger_Private("kdbg", string, &debugger);CHKERRQ(ierr); 176 ierr = PetscCheckDebugger_Private("ups", string, &debugger);CHKERRQ(ierr); 177 ierr = PetscCheckDebugger_Private("workshop", string, &debugger);CHKERRQ(ierr); 178 ierr = PetscCheckDebugger_Private("pgdbg", string, &debugger);CHKERRQ(ierr); 179 ierr = PetscCheckDebugger_Private("pathdb", string, &debugger);CHKERRQ(ierr); 180 ierr = PetscCheckDebugger_Private("lldb", string, &debugger);CHKERRQ(ierr); 181 182 ierr = PetscSetDebugger(debugger, xterm);CHKERRQ(ierr); 183 PetscFunctionReturn(0); 184 } 185 186 187 #undef __FUNCT__ 188 #define __FUNCT__ "PetscAttachDebugger" 189 /*@ 190 PetscAttachDebugger - Attaches the debugger to the running process. 191 192 Not Collective 193 194 Level: advanced 195 196 Concepts: debugger^starting from program 197 198 Developer Notes: Since this can be called by the error handler should it be calling SETERRQ() and CHKERRQ()? 199 200 .seealso: PetscSetDebugger() 201 @*/ 202 PetscErrorCode PetscAttachDebugger(void) 203 { 204 #if !defined(PETSC_CANNOT_START_DEBUGGER) 205 int child =0; 206 PetscReal sleeptime=0; 207 PetscErrorCode ierr; 208 char program[PETSC_MAX_PATH_LEN],display[256],hostname[64]; 209 #endif 210 211 PetscFunctionBegin; 212 #if defined(PETSC_CANNOT_START_DEBUGGER) || !defined(PETSC_HAVE_FORK) 213 (*PetscErrorPrintf)("System cannot start debugger\n"); 214 (*PetscErrorPrintf)("On Cray run program in Totalview debugger\n"); 215 (*PetscErrorPrintf)("On Windows use Developer Studio(MSDEV)\n"); 216 MPI_Abort(PETSC_COMM_WORLD,1); 217 #else 218 ierr = PetscGetDisplay(display,128);CHKERRQ(ierr); 219 ierr = PetscGetProgramName(program,PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 220 if (ierr) { 221 (*PetscErrorPrintf)("Cannot determine program name\n"); 222 PetscFunctionReturn(1); 223 } 224 if (!program[0]) { 225 (*PetscErrorPrintf)("Cannot determine program name\n"); 226 PetscFunctionReturn(1); 227 } 228 child = (int)fork(); 229 if (child < 0) { 230 (*PetscErrorPrintf)("Error in fork() attaching debugger\n"); 231 PetscFunctionReturn(1); 232 } 233 234 /* 235 Swap role the parent and child. This is (I think) so that control c typed 236 in the debugger goes to the correct process. 237 */ 238 if (child) child = 0; 239 else child = (int)getppid(); 240 241 if (child) { /* I am the parent, will run the debugger */ 242 const char *args[10]; 243 char pid[10]; 244 PetscInt j,jj; 245 PetscBool isdbx,isidb,isxldb,isxxgdb,isups,isxdb,isworkshop,isddd,iskdbg,islldb; 246 247 ierr = PetscGetHostName(hostname,64);CHKERRQ(ierr); 248 /* 249 We need to send a continue signal to the "child" process on the 250 alpha, otherwise it just stays off forever 251 */ 252 #if defined(PETSC_NEED_KILL_FOR_DEBUGGER) 253 kill(child,SIGCONT); 254 #endif 255 sprintf(pid,"%d",child); 256 257 ierr = PetscStrcmp(PetscDebugger,"xxgdb",&isxxgdb);CHKERRQ(ierr); 258 ierr = PetscStrcmp(PetscDebugger,"ddd",&isddd);CHKERRQ(ierr); 259 ierr = PetscStrcmp(PetscDebugger,"kdbg",&iskdbg);CHKERRQ(ierr); 260 ierr = PetscStrcmp(PetscDebugger,"ups",&isups);CHKERRQ(ierr); 261 ierr = PetscStrcmp(PetscDebugger,"xldb",&isxldb);CHKERRQ(ierr); 262 ierr = PetscStrcmp(PetscDebugger,"xdb",&isxdb);CHKERRQ(ierr); 263 ierr = PetscStrcmp(PetscDebugger,"dbx",&isdbx);CHKERRQ(ierr); 264 ierr = PetscStrcmp(PetscDebugger,"idb",&isidb);CHKERRQ(ierr); 265 ierr = PetscStrcmp(PetscDebugger,"workshop",&isworkshop);CHKERRQ(ierr); 266 ierr = PetscStrcmp(PetscDebugger,"lldb",&islldb);CHKERRQ(ierr); 267 268 if (isxxgdb || isups || isddd) { 269 args[1] = program; args[2] = pid; args[3] = "-display"; 270 args[0] = PetscDebugger; args[4] = display; args[5] = 0; 271 (*PetscErrorPrintf)("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname); 272 if (execvp(args[0],(char**)args) < 0) { 273 perror("Unable to start debugger"); 274 exit(0); 275 } 276 } else if (iskdbg) { 277 args[1] = "-p"; args[2] = pid; args[3] = program; args[4] = "-display"; 278 args[0] = PetscDebugger; args[5] = display; args[6] = 0; 279 (*PetscErrorPrintf)("PETSC: Attaching %s to %s %s on %s\n",args[0],args[3],pid,hostname); 280 if (execvp(args[0],(char**)args) < 0) { 281 perror("Unable to start debugger"); 282 exit(0); 283 } 284 } else if (isxldb) { 285 args[1] = "-a"; args[2] = pid; args[3] = program; args[4] = "-display"; 286 args[0] = PetscDebugger; args[5] = display; args[6] = 0; 287 (*PetscErrorPrintf)("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname); 288 if (execvp(args[0],(char**)args) < 0) { 289 perror("Unable to start debugger"); 290 exit(0); 291 } 292 } else if (isworkshop) { 293 args[1] = "-s"; args[2] = pid; args[3] = "-D"; args[4] = "-"; 294 args[0] = PetscDebugger; args[5] = pid; args[6] = "-display"; args[7] = display; args[8] = 0; 295 (*PetscErrorPrintf)("PETSC: Attaching %s to %s on %s\n",args[0],pid,hostname); 296 if (execvp(args[0],(char**)args) < 0) { 297 perror("Unable to start debugger"); 298 exit(0); 299 } 300 } else { 301 j = 0; 302 if (Xterm) { 303 PetscBool cmp; 304 char *tmp,*tmp1; 305 ierr = PetscStrncmp(DebugTerminal,"screen",6,&cmp);CHKERRQ(ierr); 306 if (cmp) display[0] = 0; /* when using screen, we never pass -display */ 307 args[j++] = tmp = DebugTerminal; 308 if (display[0]) { 309 args[j++] = "-display"; args[j++] = display; 310 } 311 while (*tmp) { 312 ierr = PetscStrchr(tmp,' ',&tmp1);CHKERRQ(ierr); 313 if (!tmp1) break; 314 *tmp1 = 0; 315 tmp = tmp1+1; 316 args[j++] = tmp; 317 } 318 } 319 args[j++] = PetscDebugger; 320 jj = j; 321 args[j++] = program; args[j++] = pid; args[j++] = 0; 322 323 if (isidb) { 324 j = jj; 325 args[j++] = "-pid"; 326 args[j++] = pid; 327 args[j++] = "-gdb"; 328 args[j++] = program; 329 args[j++] = 0; 330 } 331 if (islldb) { 332 j = jj; 333 args[j++] = "-p"; 334 args[j++] = pid; 335 args[j++] = 0; 336 } 337 if (isdbx) { 338 j = jj; 339 #if defined(PETSC_USE_P_FOR_DEBUGGER) 340 args[j++] = "-p"; 341 args[j++] = pid; 342 args[j++] = program; 343 #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER) 344 args[j++] = "-l"; 345 args[j++] = "ALL"; 346 args[j++] = "-P"; 347 args[j++] = pid; 348 args[j++] = program; 349 #elif defined(PETSC_USE_A_FOR_DEBUGGER) 350 args[j++] = "-a"; 351 args[j++] = pid; 352 #elif defined(PETSC_USE_PID_FOR_DEBUGGER) 353 args[j++] = "-pid"; 354 args[j++] = pid; 355 args[j++] = program; 356 #endif 357 args[j++] = 0; 358 } 359 if (Xterm) { 360 if (display[0]) (*PetscErrorPrintf)("PETSC: Attaching %s to %s of pid %s on display %s on machine %s\n",PetscDebugger,program,pid,display,hostname); 361 else (*PetscErrorPrintf)("PETSC: Attaching %s to %s on pid %s on %s\n",PetscDebugger,program,pid,hostname); 362 363 if (execvp(args[0],(char**)args) < 0) { 364 perror("Unable to start debugger in xterm"); 365 exit(0); 366 } 367 } else { 368 (*PetscErrorPrintf)("PETSC: Attaching %s to %s of pid %s on %s\n",PetscDebugger,program,pid,hostname); 369 if (execvp(args[0],(char**)args) < 0) { 370 perror("Unable to start debugger"); 371 exit(0); 372 } 373 } 374 } 375 } else { /* I am the child, continue with user code */ 376 sleeptime = 10; /* default to sleep waiting for debugger */ 377 ierr = PetscOptionsGetReal(NULL,"-debugger_pause",&sleeptime,NULL);CHKERRQ(ierr); 378 if (sleeptime < 0) sleeptime = -sleeptime; 379 #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP) 380 /* 381 HP cannot attach process to sleeping debugger, hence count instead 382 */ 383 { 384 PetscReal x = 1.0; 385 int i =10000000; 386 while (i--) x++; /* cannot attach to sleeper */ 387 } 388 #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY) 389 /* 390 IBM sleep may return at anytime, hence must see if there is more time to sleep 391 */ 392 { 393 int left = sleeptime; 394 while (left > 0) left = PetscSleep(left) - 1; 395 } 396 #else 397 PetscSleep(sleeptime); 398 #endif 399 } 400 #endif 401 PetscFunctionReturn(0); 402 } 403 404 #undef __FUNCT__ 405 #define __FUNCT__ "PetscAttachDebuggerErrorHandler" 406 /*@C 407 PetscAttachDebuggerErrorHandler - Error handler that attaches 408 a debugger to a running process when an error is detected. 409 This routine is useful for examining variables, etc. 410 411 Not Collective 412 413 Input Parameters: 414 + comm - communicator over which error occurred 415 . line - the line number of the error (indicated by __LINE__) 416 . fun - function where error occured (indicated by __FUNCT__) 417 . file - the file in which the error was detected (indicated by __FILE__) 418 . message - an error text string, usually just printed to the screen 419 . number - the generic error number 420 . p - PETSC_ERROR_INITIAL if error just detected, otherwise PETSC_ERROR_REPEAT 421 - ctx - error handler context 422 423 Options Database Keys: 424 . -on_error_attach_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] - Activates 425 debugger attachment 426 427 Level: developer 428 429 Notes: 430 By default the GNU debugger, gdb, is used. Alternatives are lldb, dbx and 431 xxgdb,xldb (on IBM rs6000), xdb (on HP-UX). 432 433 Most users need not directly employ this routine and the other error 434 handlers, but can instead use the simplified interface SETERR, which has 435 the calling sequence 436 $ SETERRQ(PETSC_COMM_SELF,number,p,message) 437 438 Notes for experienced users: 439 Use PetscPushErrorHandler() to set the desired error handler. The 440 currently available PETSc error handlers are 441 $ PetscTraceBackErrorHandler() 442 $ PetscAttachDebuggerErrorHandler() 443 $ PetscAbortErrorHandler() 444 or you may write your own. 445 446 Concepts: debugger^error handler 447 Concepts: error handler^attach debugger 448 449 .seealso: PetscPushErrorHandler(), PetscTraceBackErrorHandler(), 450 PetscAbortErrorHandler() 451 @*/ 452 PetscErrorCode PetscAttachDebuggerErrorHandler(MPI_Comm comm,int line,const char *fun,const char *file,PetscErrorCode num,PetscErrorType p,const char *mess,void *ctx) 453 { 454 PetscErrorCode ierr; 455 456 PetscFunctionBegin; 457 if (!fun) fun = "User provided function"; 458 if (!mess) mess = " "; 459 460 (*PetscErrorPrintf)("%s() line %d in %s %s\n",fun,line,file,mess); 461 462 ierr = PetscAttachDebugger(); 463 if (ierr) abort(); /* call abort because don't want to kill other MPI processes that may successfully attach to debugger */ 464 PetscFunctionReturn(0); 465 } 466 467 #undef __FUNCT__ 468 #define __FUNCT__ "PetscStopForDebugger" 469 /*@C 470 PetscStopForDebugger - Prints a message to the screen indicating how to 471 attach to the process with the debugger and then waits for the 472 debugger to attach. 473 474 Not Collective 475 476 Level: developer 477 478 Notes: This is likely never needed since PetscAttachDebugger() is easier to use and seems to always work. 479 480 Developer Notes: Since this can be called by the error handler, should it be calling SETERRQ() and CHKERRQ()? 481 482 Concepts: debugger^waiting for attachment 483 484 .seealso: PetscSetDebugger(), PetscAttachDebugger() 485 @*/ 486 PetscErrorCode PetscStopForDebugger(void) 487 { 488 PetscErrorCode ierr; 489 PetscInt sleeptime=0; 490 #if !defined(PETSC_CANNOT_START_DEBUGGER) 491 int ppid; 492 PetscMPIInt rank; 493 char program[PETSC_MAX_PATH_LEN],hostname[256]; 494 PetscBool isdbx,isxldb,isxxgdb,isddd,iskdbg,isups,isxdb,islldb; 495 #endif 496 497 PetscFunctionBegin; 498 #if defined(PETSC_CANNOT_START_DEBUGGER) 499 (*PetscErrorPrintf)("System cannot start debugger; just continuing program\n"); 500 #else 501 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank); 502 if (ierr) rank = 0; /* ignore error since this may be already in error handler */ 503 ierr = PetscGetHostName(hostname,256); 504 if (ierr) { 505 (*PetscErrorPrintf)("Cannot determine hostname; just continuing program\n"); 506 PetscFunctionReturn(0); 507 } 508 509 ierr = PetscGetProgramName(program,256); 510 if (ierr) { 511 (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n"); 512 PetscFunctionReturn(0); 513 } 514 if (!program[0]) { 515 (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n"); 516 PetscFunctionReturn(0); 517 } 518 519 ppid = getpid(); 520 521 ierr = PetscStrcmp(PetscDebugger,"xxgdb",&isxxgdb);CHKERRQ(ierr); 522 ierr = PetscStrcmp(PetscDebugger,"ddd",&isddd);CHKERRQ(ierr); 523 ierr = PetscStrcmp(PetscDebugger,"kdbg",&iskdbg);CHKERRQ(ierr); 524 ierr = PetscStrcmp(PetscDebugger,"ups",&isups);CHKERRQ(ierr); 525 ierr = PetscStrcmp(PetscDebugger,"xldb",&isxldb);CHKERRQ(ierr); 526 ierr = PetscStrcmp(PetscDebugger,"xdb",&isxdb);CHKERRQ(ierr); 527 ierr = PetscStrcmp(PetscDebugger,"dbx",&isdbx);CHKERRQ(ierr); 528 ierr = PetscStrcmp(PetscDebugger,"lldb",&islldb);CHKERRQ(ierr); 529 530 if (isxxgdb || isups || isddd || iskdbg) (*PetscErrorPrintf)("[%d]%s>>%s %s %d\n",rank,hostname,PetscDebugger,program,ppid); 531 else if (isxldb) (*PetscErrorPrintf)("[%d]%s>>%s -a %d %s\n",rank,hostname,PetscDebugger,ppid,program); 532 else if (islldb) (*PetscErrorPrintf)("[%d]%s>>%s -p %d\n",rank,hostname,PetscDebugger,ppid); 533 else if (isdbx) { 534 #if defined(PETSC_USE_P_FOR_DEBUGGER) 535 (*PetscErrorPrintf)("[%d]%s>>%s -p %d %s\n",rank,hostname,PetscDebugger,ppid,program); 536 #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER) 537 (*PetscErrorPrintf)("[%d]%s>>%s -l ALL -P %d %s\n",rank,hostname,PetscDebugger,ppid,program); 538 #elif defined(PETSC_USE_A_FOR_DEBUGGER) 539 (*PetscErrorPrintf)("[%d]%s>>%s -a %d\n",rank,hostname,PetscDebugger,ppid); 540 #elif defined(PETSC_USE_PID_FOR_DEBUGGER) 541 (*PetscErrorPrintf)("[%d]%s>>%s -pid %d %s\n",rank,hostname,PetscDebugger,ppid,program); 542 #else 543 (*PetscErrorPrintf)("[%d]%s>>%s %s %d\n",rank,hostname,PetscDebugger,program,ppid); 544 #endif 545 } 546 #endif /* PETSC_CANNOT_START_DEBUGGER */ 547 548 fflush(stdout); /* ignore error because may already be in error handler */ 549 550 sleeptime = 25; /* default to sleep waiting for debugger */ 551 PetscOptionsGetInt(NULL,"-debugger_pause",&sleeptime,NULL); /* ignore error because may already be in error handler */ 552 if (sleeptime < 0) sleeptime = -sleeptime; 553 #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP) 554 /* 555 HP cannot attach process to sleeping debugger, hence count instead 556 */ 557 { 558 PetscReal x = 1.0; 559 int i =10000000; 560 while (i--) x++; /* cannot attach to sleeper */ 561 } 562 #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY) 563 /* 564 IBM sleep may return at anytime, hence must see if there is more time to sleep 565 */ 566 { 567 int left = sleeptime; 568 while (left > 0) left = sleep(left) - 1; 569 } 570 #else 571 PetscSleep(sleeptime); 572 #endif 573 PetscFunctionReturn(0); 574 } 575 576 577 578