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