1 #define PETSC_DLL 2 /* 3 Code to handle PETSc starting up in debuggers,etc. 4 */ 5 6 #include "petscsys.h" /*I "petscsys.h" I*/ 7 #include <signal.h> 8 #if defined(PETSC_HAVE_UNISTD_H) 9 #include <unistd.h> 10 #endif 11 #if defined(PETSC_HAVE_STDLIB_H) 12 #include <stdlib.h> 13 #endif 14 15 /* 16 These are the debugger and display used if the debugger is started up 17 */ 18 static char Debugger[PETSC_MAX_PATH_LEN]; 19 static char DebugTerminal[PETSC_MAX_PATH_LEN]; 20 static PetscTruth Xterm = PETSC_TRUE; 21 22 #undef __FUNCT__ 23 #define __FUNCT__ "PetscSetDebugTerminal" 24 /*@C 25 PetscSetDebugTerminal - Sets the terminal to use (instead of xterm) for debugging. 26 27 Not Collective 28 29 Input Parameters: 30 + terminal - name of terminal and any flags required to execute a program. 31 For example "xterm -e", "urxvt -e". 32 33 Options Database Keys: 34 -debug_terminal terminal - use this terminal instead of xterm 35 36 Level: developer 37 38 Notes: 39 You can start the debugger for all processes in the same GNU screen session. 40 41 mpirun -n 4 ./myapp -start_in_debugger -debug_terminal "screen -X -S debug screen" 42 43 will open 4 windows in the session named "debug". 44 45 Fortran Note: 46 This routine is not supported in Fortran. 47 48 Concepts: debugger^setting 49 50 .seealso: PetscSetDebugger() 51 @*/ 52 PetscErrorCode PETSC_DLLEXPORT PetscSetDebugTerminal(const char terminal[]) 53 { 54 PetscErrorCode ierr; 55 56 PetscFunctionBegin; 57 ierr = PetscStrcpy(DebugTerminal,terminal);CHKERRQ(ierr); 58 PetscFunctionReturn(0); 59 } 60 61 #undef __FUNCT__ 62 #define __FUNCT__ "PetscSetDebugger" 63 /*@C 64 PetscSetDebugger - Sets options associated with the debugger. 65 66 Not Collective 67 68 Input Parameters: 69 + debugger - name of debugger, which should be in your path, 70 usually "dbx", "gdb", "idb", "xxgdb", "kdgb" or "ddd". Also, HP-UX 71 supports "xdb", and IBM rs6000 supports "xldb". 72 73 - xterm - flag to indicate debugger window, set to either 1 (to indicate 74 debugger should be started in a new xterm) or 0 (to start debugger 75 in initial window (the option 0 makes no sense when using more 76 than one processor.) 77 78 Level: developer 79 80 Fortran Note: 81 This routine is not supported in Fortran. 82 83 Concepts: debugger^setting 84 85 .seealso: PetscAttachDebugger(), PetscAttachDebuggerErrorHandler() 86 @*/ 87 PetscErrorCode PETSC_DLLEXPORT PetscSetDebugger(const char debugger[],PetscTruth xterm) 88 { 89 PetscErrorCode ierr; 90 91 PetscFunctionBegin; 92 if (debugger) { 93 ierr = PetscStrcpy(Debugger,debugger);CHKERRQ(ierr); 94 } 95 Xterm = xterm; 96 97 PetscFunctionReturn(0); 98 } 99 100 #undef __FUNCT__ 101 #define __FUNCT__ "PetscSetDefaultDebugger" 102 /*@ 103 PetscSetDefaultDebugger - Causes PETSc to use its default 104 debugger. 105 106 Not collective 107 108 Level: advanced 109 110 .seealso: PetscSetDebugger(), PetscSetDebuggerFromString() 111 @*/ 112 PetscErrorCode PETSC_DLLEXPORT PetscSetDefaultDebugger(void) 113 { 114 PetscErrorCode ierr; 115 116 PetscFunctionBegin; 117 #if defined(PETSC_USE_DBX_DEBUGGER) 118 ierr = PetscSetDebugger("dbx",PETSC_TRUE);CHKERRQ(ierr); 119 #elif defined(PETSC_USE_XDB_DEBUGGER) 120 ierr = PetscSetDebugger("xdb",PETSC_TRUE);CHKERRQ(ierr); 121 #elif defined(PETSC_USE_IDB_DEBUGGER) 122 ierr = PetscSetDebugger("idb",PETSC_TRUE);CHKERRQ(ierr); 123 #else /* Default is gdb */ 124 ierr = PetscSetDebugger("gdb",PETSC_TRUE);CHKERRQ(ierr); 125 #endif 126 ierr = PetscSetDebugTerminal("xterm -e");CHKERRQ(ierr); 127 PetscFunctionReturn(0); 128 } 129 130 #undef __FUNCT__ 131 #define __FUNCT__ "PetscCheckDebugger_Private" 132 static PetscErrorCode PetscCheckDebugger_Private(const char defaultDbg[], const char string[], const char *debugger[]) 133 { 134 PetscTruth exists; 135 char *f; 136 PetscErrorCode ierr; 137 138 PetscFunctionBegin; 139 ierr = PetscStrstr(string, defaultDbg, &f);CHKERRQ(ierr); 140 if (f) { 141 ierr = PetscTestFile(string, 'x', &exists);CHKERRQ(ierr); 142 if (exists) { 143 *debugger = string; 144 } else { 145 *debugger = defaultDbg; 146 } 147 } 148 PetscFunctionReturn(0); 149 } 150 151 #undef __FUNCT__ 152 #define __FUNCT__ "PetscSetDebuggerFromString" 153 /*@C 154 PetscSetDebuggerFromString - Set the complete path for the 155 debugger for PETSc to use. 156 157 Not collective 158 159 Level: advanced 160 161 .seealso: PetscSetDebugger(), PetscSetDefaultDebugger() 162 @*/ 163 PetscErrorCode PETSC_DLLEXPORT PetscSetDebuggerFromString(char *string) 164 { 165 const char *debugger = PETSC_NULL; 166 PetscTruth xterm = PETSC_TRUE; 167 char *f; 168 PetscErrorCode ierr; 169 170 PetscFunctionBegin; 171 ierr = PetscStrstr(string, "noxterm", &f);CHKERRQ(ierr); 172 if (f) xterm = PETSC_FALSE; 173 ierr = PetscStrstr(string, "ddd", &f);CHKERRQ(ierr); 174 if (f) xterm = PETSC_FALSE; 175 ierr = PetscCheckDebugger_Private("xdb", string, &debugger);CHKERRQ(ierr); 176 ierr = PetscCheckDebugger_Private("dbx", string, &debugger);CHKERRQ(ierr); 177 ierr = PetscCheckDebugger_Private("xldb", string, &debugger);CHKERRQ(ierr); 178 ierr = PetscCheckDebugger_Private("gdb", string, &debugger);CHKERRQ(ierr); 179 ierr = PetscCheckDebugger_Private("idb", string, &debugger);CHKERRQ(ierr); 180 ierr = PetscCheckDebugger_Private("xxgdb", string, &debugger);CHKERRQ(ierr); 181 ierr = PetscCheckDebugger_Private("ddd", string, &debugger);CHKERRQ(ierr); 182 ierr = PetscCheckDebugger_Private("kdbg", string, &debugger);CHKERRQ(ierr); 183 ierr = PetscCheckDebugger_Private("ups", string, &debugger);CHKERRQ(ierr); 184 ierr = PetscCheckDebugger_Private("workshop", string, &debugger);CHKERRQ(ierr); 185 ierr = PetscCheckDebugger_Private("pgdbg", string, &debugger);CHKERRQ(ierr); 186 ierr = PetscCheckDebugger_Private("pathdb", string, &debugger);CHKERRQ(ierr); 187 188 ierr = PetscSetDebugger(debugger, xterm);CHKERRQ(ierr); 189 PetscFunctionReturn(0); 190 } 191 192 193 #undef __FUNCT__ 194 #define __FUNCT__ "PetscAttachDebugger" 195 /*@ 196 PetscAttachDebugger - Attaches the debugger to the running process. 197 198 Not Collective 199 200 Level: advanced 201 202 Concepts: debugger^starting from program 203 204 .seealso: PetscSetDebugger() 205 @*/ 206 PetscErrorCode PETSC_DLLEXPORT 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_Finalize(); 222 exit(0); 223 #else 224 ierr = PetscGetDisplay(display,128);CHKERRQ(ierr); 225 ierr = PetscGetProgramName(program,PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 226 if (ierr) { 227 (*PetscErrorPrintf)("Cannot determine program name\n"); 228 PetscFunctionReturn(1); 229 } 230 if (!program[0]) { 231 (*PetscErrorPrintf)("Cannot determine program name\n"); 232 PetscFunctionReturn(1); 233 } 234 child = (int)fork(); 235 if (child < 0) { 236 (*PetscErrorPrintf)("Error in fork() attaching debugger\n"); 237 PetscFunctionReturn(1); 238 } 239 240 /* 241 Swap role the parent and child. This is (I think) so that control c typed 242 in the debugger goes to the correct process. 243 */ 244 if (child) { child = 0; } 245 else { child = (int)getppid(); } 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 PetscTruth isdbx,isidb,isxldb,isxxgdb,isups,isxdb,isworkshop,isddd,iskdbg; 252 253 ierr = PetscGetHostName(hostname,64);CHKERRQ(ierr); 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 ierr = PetscStrcmp(Debugger,"xxgdb",&isxxgdb);CHKERRQ(ierr); 264 ierr = PetscStrcmp(Debugger,"ddd",&isddd);CHKERRQ(ierr); 265 ierr = PetscStrcmp(Debugger,"kdbg",&iskdbg);CHKERRQ(ierr); 266 ierr = PetscStrcmp(Debugger,"ups",&isups);CHKERRQ(ierr); 267 ierr = PetscStrcmp(Debugger,"xldb",&isxldb);CHKERRQ(ierr); 268 ierr = PetscStrcmp(Debugger,"xdb",&isxdb);CHKERRQ(ierr); 269 ierr = PetscStrcmp(Debugger,"dbx",&isdbx);CHKERRQ(ierr); 270 ierr = PetscStrcmp(Debugger,"idb",&isidb);CHKERRQ(ierr); 271 ierr = PetscStrcmp(Debugger,"workshop",&isworkshop);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 PetscTruth 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 defined(PETSC_USE_P_FOR_DEBUGGER) 337 if (isdbx) { 338 j = jj; 339 args[j++] = "-p"; 340 args[j++] = pid; 341 args[j++] = program; 342 args[j++] = 0; 343 } 344 #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER) 345 if (isxdb) { 346 j = jj; 347 args[j++] = "-l"; 348 args[j++] = "ALL"; 349 args[j++] = "-P"; 350 args[j++] = pid; 351 args[j++] = program; 352 args[j++] = 0; 353 } 354 #elif defined(PETSC_USE_A_FOR_DEBUGGER) 355 if (isdbx) { 356 j = jj; 357 args[j++] = "-a"; 358 args[j++] = pid; 359 args[j++] = 0; 360 } 361 #elif defined(PETSC_USE_PID_FOR_DEBUGGER) 362 if (isdbx) { 363 j = jj; 364 args[j++] = "-pid"; 365 args[j++] = pid; 366 args[j++] = program; 367 args[j++] = 0; 368 } 369 #endif 370 if (Xterm) { 371 if (display[0]) { 372 (*PetscErrorPrintf)("PETSC: Attaching %s to %s of pid %s on display %s on machine %s\n",Debugger,program,pid,display,hostname); 373 } else { 374 (*PetscErrorPrintf)("PETSC: Attaching %s to %s on pid %s on %s\n",Debugger,program,pid,hostname); 375 } 376 if (execvp(args[0],(char**)args) < 0) { 377 perror("Unable to start debugger in xterm"); 378 exit(0); 379 } 380 } else { 381 (*PetscErrorPrintf)("PETSC: Attaching %s to %s of pid %s on %s\n",Debugger,program,pid,hostname); 382 if (execvp(args[0],(char**)args) < 0) { 383 perror("Unable to start debugger"); 384 exit(0); 385 } 386 } 387 } 388 } else { /* I am the child, continue with user code */ 389 sleeptime = 10; /* default to sleep waiting for debugger */ 390 ierr = PetscOptionsGetReal(PETSC_NULL,"-debugger_pause",&sleeptime,PETSC_NULL);CHKERRQ(ierr); 391 if (sleeptime < 0) sleeptime = -sleeptime; 392 #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP) 393 /* 394 HP cannot attach process to sleeping debugger, hence count instead 395 */ 396 { 397 PetscReal x = 1.0; 398 int i=10000000; 399 while (i--) x++ ; /* cannot attach to sleeper */ 400 } 401 #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY) 402 /* 403 IBM sleep may return at anytime, hence must see if there is more time to sleep 404 */ 405 { 406 int left = sleeptime; 407 while (left > 0) {left = PetscSleep(left) - 1;} 408 } 409 #else 410 PetscSleep(sleeptime); 411 #endif 412 } 413 #endif 414 PetscFunctionReturn(0); 415 } 416 417 #undef __FUNCT__ 418 #define __FUNCT__ "PetscAttachDebuggerErrorHandler" 419 /*@C 420 PetscAttachDebuggerErrorHandler - Error handler that attaches 421 a debugger to a running process when an error is detected. 422 This routine is useful for examining variables, etc. 423 424 Not Collective 425 426 Input Parameters: 427 + comm - communicator over which error occurred 428 . line - the line number of the error (indicated by __LINE__) 429 . fun - function where error occured (indicated by __FUNCT__) 430 . file - the file in which the error was detected (indicated by __FILE__) 431 . dir - the directory of the file (indicated by __SDIR__) 432 . message - an error text string, usually just printed to the screen 433 . number - the generic error number 434 . p - the specific error number 435 - ctx - error handler context 436 437 Options Database Keys: 438 . -on_error_attach_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] - Activates 439 debugger attachment 440 441 Level: developer 442 443 Notes: 444 By default the GNU debugger, gdb, is used. Alternatives are dbx and 445 xxgdb,xldb (on IBM rs6000), xdb (on HP-UX). 446 447 Most users need not directly employ this routine and the other error 448 handlers, but can instead use the simplified interface SETERR, which has 449 the calling sequence 450 $ SETERRQ(PETSC_COMM_SELF,number,p,message) 451 452 Notes for experienced users: 453 Use PetscPushErrorHandler() to set the desired error handler. The 454 currently available PETSc error handlers are 455 $ PetscTraceBackErrorHandler() 456 $ PetscAttachDebuggerErrorHandler() 457 $ PetscAbortErrorHandler() 458 or you may write your own. 459 460 Concepts: debugger^error handler 461 Concepts: error handler^attach debugger 462 463 .seealso: PetscPushErrorHandler(), PetscTraceBackErrorHandler(), 464 PetscAbortErrorHandler() 465 @*/ 466 PetscErrorCode PETSC_DLLEXPORT PetscAttachDebuggerErrorHandler(MPI_Comm comm,int line,const char* fun,const char *file,const char* dir,int num,int p,const char* mess,void *ctx) 467 { 468 PetscErrorCode ierr; 469 470 PetscFunctionBegin; 471 if (!fun) fun = "User provided function"; 472 if (!dir) dir = " "; 473 if (!mess) mess = " "; 474 475 (*PetscErrorPrintf)("%s() line %d in %s%s %s\n",fun,line,dir,file,mess); 476 477 ierr = PetscAttachDebugger(); 478 if (ierr) { /* hopeless so get out */ 479 MPI_Finalize(); 480 exit(num); 481 } 482 PetscFunctionReturn(0); 483 } 484 485 #undef __FUNCT__ 486 #define __FUNCT__ "PetscStopForDebugger" 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 Level: advanced 495 496 Concepts: debugger^waiting for attachment 497 498 .seealso: PetscSetDebugger(), PetscAttachDebugger() 499 @*/ 500 PetscErrorCode PETSC_DLLEXPORT PetscStopForDebugger(void) 501 { 502 PetscErrorCode ierr; 503 PetscInt sleeptime=0; 504 int err; 505 #if !defined(PETSC_CANNOT_START_DEBUGGER) 506 int ppid; 507 PetscMPIInt rank; 508 char program[PETSC_MAX_PATH_LEN],hostname[256]; 509 PetscTruth isdbx,isxldb,isxxgdb,isddd,iskdbg,isups,isxdb; 510 #endif 511 512 PetscFunctionBegin; 513 #if defined(PETSC_CANNOT_START_DEBUGGER) 514 (*PetscErrorPrintf)("System cannot start debugger; just continuing program\n"); 515 #else 516 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank); 517 ierr = PetscGetHostName(hostname,256); 518 if (ierr) { 519 (*PetscErrorPrintf)("Cannot determine hostname; just continuing program\n"); 520 PetscFunctionReturn(0); 521 } 522 523 ierr = PetscGetProgramName(program,256); 524 if (ierr) { 525 (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n"); 526 PetscFunctionReturn(0); 527 } 528 if (!program[0]) { 529 (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n"); 530 PetscFunctionReturn(0); 531 } 532 533 ppid = getpid(); 534 535 ierr = PetscStrcmp(Debugger,"xxgdb",&isxxgdb);CHKERRQ(ierr); 536 ierr = PetscStrcmp(Debugger,"ddd",&isddd);CHKERRQ(ierr); 537 ierr = PetscStrcmp(Debugger,"kdbg",&iskdbg);CHKERRQ(ierr); 538 ierr = PetscStrcmp(Debugger,"ups",&isups);CHKERRQ(ierr); 539 ierr = PetscStrcmp(Debugger,"xldb",&isxldb);CHKERRQ(ierr); 540 ierr = PetscStrcmp(Debugger,"xdb",&isxdb);CHKERRQ(ierr); 541 ierr = PetscStrcmp(Debugger,"dbx",&isdbx);CHKERRQ(ierr); 542 543 if (isxxgdb || isups || isddd || iskdbg ) { 544 (*PetscErrorPrintf)("[%d]%s>>%s %s %d\n",rank,hostname,Debugger,program,ppid); 545 } 546 #if defined(PETSC_USE_A_FOR_DEBUGGER) 547 else if (isxldb) { 548 (*PetscErrorPrintf)("{%d]%s>>%s -a %d %s\n",rank,hostname,Debugger,ppid,program); 549 } 550 #endif 551 #if defined(PETSC_USE_P_FOR_DEBUGGER) 552 else if (isdbx) { 553 (*PetscErrorPrintf)("[%d]%s>>%s -p %d %s\n",rank,hostname,Debugger,ppid,program); 554 } 555 #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER) 556 else if (isxdb) { 557 (*PetscErrorPrintf)("[%d]%s>>%s -l ALL -P %d %s\n",rank,hostname,Debugger,ppid,program); 558 } 559 #elif defined(PETSC_USE_A_FOR_DEBUGGER) 560 else if (isdbx) { 561 (*PetscErrorPrintf)("[%d]%s>>%s -a %d\n",rank,hostname,Debugger,ppid); 562 } 563 #elif defined(PETSC_USE_PID_FOR_DEBUGGER) 564 else if (isdbx) { 565 (*PetscErrorPrintf)("[%d]%s>>%s -pid %d %s\n",rank,hostname,Debugger,ppid,program); 566 } 567 #else 568 else { 569 (*PetscErrorPrintf)("[%d]%s>>%s %s %d\n",rank,hostname,Debugger,program,ppid); 570 } 571 #endif 572 #endif /* PETSC_CANNOT_START_DEBUGGER */ 573 574 err = fflush(stdout); 575 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on stdout"); 576 577 sleeptime = 25; /* default to sleep waiting for debugger */ 578 ierr = PetscOptionsGetInt(PETSC_NULL,"-debugger_pause",&sleeptime,PETSC_NULL);CHKERRQ(ierr); 579 if (sleeptime < 0) sleeptime = -sleeptime; 580 #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP) 581 /* 582 HP cannot attach process to sleeping debugger, hence count instead 583 */ 584 { 585 PetscReal x = 1.0; 586 int i=10000000; 587 while (i--) x++ ; /* cannot attach to sleeper */ 588 } 589 #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY) 590 /* 591 IBM sleep may return at anytime, hence must see if there is more time to sleep 592 */ 593 { 594 int left = sleeptime; 595 while (left > 0) {left = sleep(left) - 1;} 596 } 597 #else 598 PetscSleep(sleeptime); 599 #endif 600 PetscFunctionReturn(0); 601 } 602 603 604 605