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