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 PETSCSYS_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 PETSCSYS_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 PetscFunctionReturn(0); 97 } 98 99 #undef __FUNCT__ 100 #define __FUNCT__ "PetscSetDefaultDebugger" 101 /*@ 102 PetscSetDefaultDebugger - Causes PETSc to use its default debugger. 103 104 Not collective 105 106 Level: advanced 107 108 .seealso: PetscSetDebugger(), PetscSetDebuggerFromString() 109 @*/ 110 PetscErrorCode PETSCSYS_DLLEXPORT PetscSetDefaultDebugger(void) 111 { 112 PetscErrorCode ierr; 113 114 PetscFunctionBegin; 115 #if defined(PETSC_USE_DBX_DEBUGGER) 116 ierr = PetscSetDebugger("dbx",PETSC_TRUE);CHKERRQ(ierr); 117 #elif defined(PETSC_USE_XDB_DEBUGGER) 118 ierr = PetscSetDebugger("xdb",PETSC_TRUE);CHKERRQ(ierr); 119 #elif defined(PETSC_USE_IDB_DEBUGGER) 120 ierr = PetscSetDebugger("idb",PETSC_TRUE);CHKERRQ(ierr); 121 #else /* Default is gdb */ 122 ierr = PetscSetDebugger("gdb",PETSC_TRUE);CHKERRQ(ierr); 123 #endif 124 ierr = PetscSetDebugTerminal("xterm -e");CHKERRQ(ierr); 125 PetscFunctionReturn(0); 126 } 127 128 #undef __FUNCT__ 129 #define __FUNCT__ "PetscCheckDebugger_Private" 130 static PetscErrorCode PetscCheckDebugger_Private(const char defaultDbg[], const char string[], const char *debugger[]) 131 { 132 PetscTruth exists; 133 char *f; 134 PetscErrorCode ierr; 135 136 PetscFunctionBegin; 137 ierr = PetscStrstr(string, defaultDbg, &f);CHKERRQ(ierr); 138 if (f) { 139 ierr = PetscTestFile(string, 'x', &exists);CHKERRQ(ierr); 140 if (exists) { 141 *debugger = string; 142 } else { 143 *debugger = defaultDbg; 144 } 145 } 146 PetscFunctionReturn(0); 147 } 148 149 #undef __FUNCT__ 150 #define __FUNCT__ "PetscSetDebuggerFromString" 151 /*@C 152 PetscSetDebuggerFromString - Set the complete path for the 153 debugger for PETSc to use. 154 155 Not collective 156 157 Level: advanced 158 159 .seealso: PetscSetDebugger(), PetscSetDefaultDebugger() 160 @*/ 161 PetscErrorCode PETSCSYS_DLLEXPORT PetscSetDebuggerFromString(char *string) 162 { 163 const char *debugger = PETSC_NULL; 164 PetscTruth xterm = PETSC_TRUE; 165 char *f; 166 PetscErrorCode ierr; 167 168 PetscFunctionBegin; 169 ierr = PetscStrstr(string, "noxterm", &f);CHKERRQ(ierr); 170 if (f) xterm = PETSC_FALSE; 171 ierr = PetscStrstr(string, "ddd", &f);CHKERRQ(ierr); 172 if (f) xterm = PETSC_FALSE; 173 ierr = PetscCheckDebugger_Private("xdb", string, &debugger);CHKERRQ(ierr); 174 ierr = PetscCheckDebugger_Private("dbx", string, &debugger);CHKERRQ(ierr); 175 ierr = PetscCheckDebugger_Private("xldb", string, &debugger);CHKERRQ(ierr); 176 ierr = PetscCheckDebugger_Private("gdb", string, &debugger);CHKERRQ(ierr); 177 ierr = PetscCheckDebugger_Private("idb", string, &debugger);CHKERRQ(ierr); 178 ierr = PetscCheckDebugger_Private("xxgdb", string, &debugger);CHKERRQ(ierr); 179 ierr = PetscCheckDebugger_Private("ddd", string, &debugger);CHKERRQ(ierr); 180 ierr = PetscCheckDebugger_Private("kdbg", string, &debugger);CHKERRQ(ierr); 181 ierr = PetscCheckDebugger_Private("ups", string, &debugger);CHKERRQ(ierr); 182 ierr = PetscCheckDebugger_Private("workshop", string, &debugger);CHKERRQ(ierr); 183 ierr = PetscCheckDebugger_Private("pgdbg", string, &debugger);CHKERRQ(ierr); 184 ierr = PetscCheckDebugger_Private("pathdb", 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 PETSCSYS_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_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 PetscTruth isdbx,isidb,isxldb,isxxgdb,isups,isxdb,isworkshop,isddd,iskdbg; 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 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 PetscTruth 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 defined(PETSC_USE_P_FOR_DEBUGGER) 336 if (isdbx) { 337 j = jj; 338 args[j++] = "-p"; 339 args[j++] = pid; 340 args[j++] = program; 341 args[j++] = 0; 342 } 343 #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER) 344 if (isxdb) { 345 j = jj; 346 args[j++] = "-l"; 347 args[j++] = "ALL"; 348 args[j++] = "-P"; 349 args[j++] = pid; 350 args[j++] = program; 351 args[j++] = 0; 352 } 353 #elif defined(PETSC_USE_A_FOR_DEBUGGER) 354 if (isdbx) { 355 j = jj; 356 args[j++] = "-a"; 357 args[j++] = pid; 358 args[j++] = 0; 359 } 360 #elif defined(PETSC_USE_PID_FOR_DEBUGGER) 361 if (isdbx) { 362 j = jj; 363 args[j++] = "-pid"; 364 args[j++] = pid; 365 args[j++] = program; 366 args[j++] = 0; 367 } 368 #endif 369 if (Xterm) { 370 if (display[0]) { 371 (*PetscErrorPrintf)("PETSC: Attaching %s to %s of pid %s on display %s on machine %s\n",Debugger,program,pid,display,hostname); 372 } else { 373 (*PetscErrorPrintf)("PETSC: Attaching %s to %s on pid %s on %s\n",Debugger,program,pid,hostname); 374 } 375 if (execvp(args[0],(char**)args) < 0) { 376 perror("Unable to start debugger in xterm"); 377 exit(0); 378 } 379 } else { 380 (*PetscErrorPrintf)("PETSC: Attaching %s to %s of pid %s on %s\n",Debugger,program,pid,hostname); 381 if (execvp(args[0],(char**)args) < 0) { 382 perror("Unable to start debugger"); 383 exit(0); 384 } 385 } 386 } 387 } else { /* I am the child, continue with user code */ 388 sleeptime = 10; /* default to sleep waiting for debugger */ 389 ierr = PetscOptionsGetReal(PETSC_NULL,"-debugger_pause",&sleeptime,PETSC_NULL);CHKERRQ(ierr); 390 if (sleeptime < 0) sleeptime = -sleeptime; 391 #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP) 392 /* 393 HP cannot attach process to sleeping debugger, hence count instead 394 */ 395 { 396 PetscReal x = 1.0; 397 int i=10000000; 398 while (i--) x++ ; /* cannot attach to sleeper */ 399 } 400 #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY) 401 /* 402 IBM sleep may return at anytime, hence must see if there is more time to sleep 403 */ 404 { 405 int left = sleeptime; 406 while (left > 0) {left = PetscSleep(left) - 1;} 407 } 408 #else 409 PetscSleep(sleeptime); 410 #endif 411 } 412 #endif 413 PetscFunctionReturn(0); 414 } 415 416 #undef __FUNCT__ 417 #define __FUNCT__ "PetscAttachDebuggerErrorHandler" 418 /*@C 419 PetscAttachDebuggerErrorHandler - Error handler that attaches 420 a debugger to a running process when an error is detected. 421 This routine is useful for examining variables, etc. 422 423 Not Collective 424 425 Input Parameters: 426 + comm - communicator over which error occurred 427 . line - the line number of the error (indicated by __LINE__) 428 . fun - function where error occured (indicated by __FUNCT__) 429 . file - the file in which the error was detected (indicated by __FILE__) 430 . dir - the directory of the file (indicated by __SDIR__) 431 . message - an error text string, usually just printed to the screen 432 . number - the generic error number 433 . p - PETSC_ERROR_INITIAL if error just detected, otherwise PETSC_ERROR_REPEAT 434 - ctx - error handler context 435 436 Options Database Keys: 437 . -on_error_attach_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] - Activates 438 debugger attachment 439 440 Level: developer 441 442 Notes: 443 By default the GNU debugger, gdb, is used. Alternatives are dbx and 444 xxgdb,xldb (on IBM rs6000), xdb (on HP-UX). 445 446 Most users need not directly employ this routine and the other error 447 handlers, but can instead use the simplified interface SETERR, which has 448 the calling sequence 449 $ SETERRQ(PETSC_COMM_SELF,number,p,message) 450 451 Notes for experienced users: 452 Use PetscPushErrorHandler() to set the desired error handler. The 453 currently available PETSc error handlers are 454 $ PetscTraceBackErrorHandler() 455 $ PetscAttachDebuggerErrorHandler() 456 $ PetscAbortErrorHandler() 457 or you may write your own. 458 459 Concepts: debugger^error handler 460 Concepts: error handler^attach debugger 461 462 .seealso: PetscPushErrorHandler(), PetscTraceBackErrorHandler(), 463 PetscAbortErrorHandler() 464 @*/ 465 PetscErrorCode PETSCSYS_DLLEXPORT PetscAttachDebuggerErrorHandler(MPI_Comm comm,int line,const char* fun,const char *file,const char* dir,PetscErrorCode num,PetscErrorType p,const char* mess,void *ctx) 466 { 467 PetscErrorCode ierr; 468 469 PetscFunctionBegin; 470 if (!fun) fun = "User provided function"; 471 if (!dir) dir = " "; 472 if (!mess) mess = " "; 473 474 (*PetscErrorPrintf)("%s() line %d in %s%s %s\n",fun,line,dir,file,mess); 475 476 ierr = PetscAttachDebugger(); 477 if (ierr) { /* call abort because don't want to kill other MPI processes that may successfully attach to debugger */ 478 abort(); 479 } 480 PetscFunctionReturn(0); 481 } 482 483 #undef __FUNCT__ 484 #define __FUNCT__ "PetscStopForDebugger" 485 /*@C 486 PetscStopForDebugger - Prints a message to the screen indicating how to 487 attach to the process with the debugger and then waits for the 488 debugger to attach. 489 490 Not Collective 491 492 Level: advanced 493 494 Developer Notes: Since this can be called by the error handler should it be calling SETERRQ() and CHKERRQ()? 495 496 Concepts: debugger^waiting for attachment 497 498 .seealso: PetscSetDebugger(), PetscAttachDebugger() 499 @*/ 500 PetscErrorCode PETSCSYS_DLLEXPORT PetscStopForDebugger(void) 501 { 502 PetscErrorCode ierr; 503 PetscInt sleeptime=0; 504 #if !defined(PETSC_CANNOT_START_DEBUGGER) 505 int ppid; 506 PetscMPIInt rank; 507 char program[PETSC_MAX_PATH_LEN],hostname[256]; 508 PetscTruth isdbx,isxldb,isxxgdb,isddd,iskdbg,isups,isxdb; 509 #endif 510 511 PetscFunctionBegin; 512 #if defined(PETSC_CANNOT_START_DEBUGGER) 513 (*PetscErrorPrintf)("System cannot start debugger; just continuing program\n"); 514 #else 515 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank); 516 if (ierr) rank = 0; /* ignore error since this may be already in error handler */ 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 fflush(stdout); /* ignore error because may already be in error handler */ 575 576 sleeptime = 25; /* default to sleep waiting for debugger */ 577 PetscOptionsGetInt(PETSC_NULL,"-debugger_pause",&sleeptime,PETSC_NULL); /* ignore error because may already be in error handler */ 578 if (sleeptime < 0) sleeptime = -sleeptime; 579 #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP) 580 /* 581 HP cannot attach process to sleeping debugger, hence count instead 582 */ 583 { 584 PetscReal x = 1.0; 585 int i=10000000; 586 while (i--) x++ ; /* cannot attach to sleeper */ 587 } 588 #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY) 589 /* 590 IBM sleep may return at anytime, hence must see if there is more time to sleep 591 */ 592 { 593 int left = sleeptime; 594 while (left > 0) {left = sleep(left) - 1;} 595 } 596 #else 597 PetscSleep(sleeptime); 598 #endif 599 PetscFunctionReturn(0); 600 } 601 602 603 604