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