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