xref: /petsc/src/sys/error/adebug.c (revision e32f2f54e699d0aa6e733466c00da7e34666fe5e)
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