xref: /petsc/src/sys/error/adebug.c (revision 3f2090d5b101f83ad3b99db560935e7511b462d0)
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 +  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 - the specific error number
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(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 PETSC_DLLEXPORT PetscAttachDebuggerErrorHandler(int line,const char* fun,const char *file,const char* dir,int num,int 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) { /* hopeless so get out */
478     MPI_Finalize();
479     exit(num);
480   }
481   PetscFunctionReturn(0);
482 }
483 
484 #undef __FUNCT__
485 #define __FUNCT__ "PetscStopForDebugger"
486 /*@C
487    PetscStopForDebugger - Prints a message to the screen indicating how to
488          attach to the process with the debugger and then waits for the
489          debugger to attach.
490 
491    Not Collective
492 
493    Level: advanced
494 
495    Concepts: debugger^waiting for attachment
496 
497 .seealso: PetscSetDebugger(), PetscAttachDebugger()
498 @*/
499 PetscErrorCode PETSC_DLLEXPORT PetscStopForDebugger(void)
500 {
501   PetscErrorCode ierr;
502   PetscInt       sleeptime=0;
503   int            err;
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   ierr = PetscGetHostName(hostname,256);
517   if (ierr) {
518     (*PetscErrorPrintf)("Cannot determine hostname; just continuing program\n");
519     PetscFunctionReturn(0);
520   }
521 
522   ierr = PetscGetProgramName(program,256);
523   if (ierr) {
524     (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n");
525     PetscFunctionReturn(0);
526   }
527   if (!program[0]) {
528     (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n");
529     PetscFunctionReturn(0);
530   }
531 
532   ppid = getpid();
533 
534   ierr = PetscStrcmp(Debugger,"xxgdb",&isxxgdb);CHKERRQ(ierr);
535   ierr = PetscStrcmp(Debugger,"ddd",&isddd);CHKERRQ(ierr);
536   ierr = PetscStrcmp(Debugger,"kdbg",&iskdbg);CHKERRQ(ierr);
537   ierr = PetscStrcmp(Debugger,"ups",&isups);CHKERRQ(ierr);
538   ierr = PetscStrcmp(Debugger,"xldb",&isxldb);CHKERRQ(ierr);
539   ierr = PetscStrcmp(Debugger,"xdb",&isxdb);CHKERRQ(ierr);
540   ierr = PetscStrcmp(Debugger,"dbx",&isdbx);CHKERRQ(ierr);
541 
542   if (isxxgdb || isups || isddd || iskdbg ) {
543     (*PetscErrorPrintf)("[%d]%s>>%s %s %d\n",rank,hostname,Debugger,program,ppid);
544   }
545 #if defined(PETSC_USE_A_FOR_DEBUGGER)
546   else if (isxldb) {
547     (*PetscErrorPrintf)("{%d]%s>>%s -a %d %s\n",rank,hostname,Debugger,ppid,program);
548   }
549 #endif
550 #if defined(PETSC_USE_P_FOR_DEBUGGER)
551   else if (isdbx) {
552     (*PetscErrorPrintf)("[%d]%s>>%s -p %d %s\n",rank,hostname,Debugger,ppid,program);
553   }
554 #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER)
555   else if (isxdb) {
556     (*PetscErrorPrintf)("[%d]%s>>%s -l ALL -P %d %s\n",rank,hostname,Debugger,ppid,program);
557   }
558 #elif defined(PETSC_USE_A_FOR_DEBUGGER)
559   else if (isdbx) {
560     (*PetscErrorPrintf)("[%d]%s>>%s -a %d\n",rank,hostname,Debugger,ppid);
561   }
562 #elif defined(PETSC_USE_PID_FOR_DEBUGGER)
563   else if (isdbx) {
564     (*PetscErrorPrintf)("[%d]%s>>%s -pid %d %s\n",rank,hostname,Debugger,ppid,program);
565   }
566 #else
567   else {
568     (*PetscErrorPrintf)("[%d]%s>>%s %s %d\n",rank,hostname,Debugger,program,ppid);
569   }
570 #endif
571 #endif /* PETSC_CANNOT_START_DEBUGGER */
572 
573   err = fflush(stdout);
574   if (err) SETERRQ(PETSC_ERR_SYS,"fflush() failed on stdout");
575 
576   sleeptime = 25; /* default to sleep waiting for debugger */
577   ierr = PetscOptionsGetInt(PETSC_NULL,"-debugger_pause",&sleeptime,PETSC_NULL);CHKERRQ(ierr);
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