xref: /petsc/src/sys/error/adebug.c (revision 5c6c1daec53e1d9ab0bec9db5309fd8fc7645b8d)
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 
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     PetscBool  isdbx,isidb,isxldb,isxxgdb,isups,isxdb,isworkshop,isddd,iskdbg,islldb;
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     ierr = PetscStrcmp(Debugger,"lldb",&islldb);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         PetscBool  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 (islldb) {
337         j = jj;
338         args[j++] = "-p";
339         args[j++] = pid;
340         args[j++] = 0;
341       }
342 #if defined(PETSC_USE_P_FOR_DEBUGGER)
343       if (isdbx) {
344         j = jj;
345         args[j++] = "-p";
346         args[j++] = pid;
347         args[j++] = program;
348         args[j++] = 0;
349       }
350 #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER)
351       if (isxdb) {
352         j = jj;
353         args[j++] = "-l";
354         args[j++] = "ALL";
355         args[j++] = "-P";
356         args[j++] = pid;
357         args[j++] = program;
358         args[j++] = 0;
359       }
360 #elif defined(PETSC_USE_A_FOR_DEBUGGER)
361       if (isdbx) {
362         j = jj;
363         args[j++] = "-a";
364         args[j++] = pid;
365         args[j++] = 0;
366       }
367 #elif defined(PETSC_USE_PID_FOR_DEBUGGER)
368       if (isdbx) {
369         j = jj;
370         args[j++] = "-pid";
371         args[j++] = pid;
372         args[j++] = program;
373         args[j++] = 0;
374       }
375 #endif
376       if (Xterm) {
377         if (display[0]) {
378           (*PetscErrorPrintf)("PETSC: Attaching %s to %s of pid %s on display %s on machine %s\n",Debugger,program,pid,display,hostname);
379         } else {
380           (*PetscErrorPrintf)("PETSC: Attaching %s to %s on pid %s on %s\n",Debugger,program,pid,hostname);
381         }
382         if (execvp(args[0],(char**)args)  < 0) {
383           perror("Unable to start debugger in xterm");
384           exit(0);
385         }
386       } else {
387         (*PetscErrorPrintf)("PETSC: Attaching %s to %s of pid %s on %s\n",Debugger,program,pid,hostname);
388         if (execvp(args[0],(char**)args)  < 0) {
389           perror("Unable to start debugger");
390           exit(0);
391         }
392       }
393     }
394   } else {   /* I am the child, continue with user code */
395     sleeptime = 10; /* default to sleep waiting for debugger */
396     ierr = PetscOptionsGetReal(PETSC_NULL,"-debugger_pause",&sleeptime,PETSC_NULL);CHKERRQ(ierr);
397     if (sleeptime < 0) sleeptime = -sleeptime;
398 #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP)
399     /*
400         HP cannot attach process to sleeping debugger, hence count instead
401     */
402     {
403       PetscReal x = 1.0;
404       int i=10000000;
405       while (i--) x++ ; /* cannot attach to sleeper */
406     }
407 #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY)
408     /*
409         IBM sleep may return at anytime, hence must see if there is more time to sleep
410     */
411     {
412       int left = sleeptime;
413       while (left > 0) {left = PetscSleep(left) - 1;}
414     }
415 #else
416     PetscSleep(sleeptime);
417 #endif
418   }
419 #endif
420   PetscFunctionReturn(0);
421 }
422 
423 #undef __FUNCT__
424 #define __FUNCT__ "PetscAttachDebuggerErrorHandler"
425 /*@C
426    PetscAttachDebuggerErrorHandler - Error handler that attaches
427    a debugger to a running process when an error is detected.
428    This routine is useful for examining variables, etc.
429 
430    Not Collective
431 
432    Input Parameters:
433 +  comm - communicator over which error occurred
434 .  line - the line number of the error (indicated by __LINE__)
435 .  fun - function where error occured (indicated by __FUNCT__)
436 .  file - the file in which the error was detected (indicated by __FILE__)
437 .  dir - the directory of the file (indicated by __SDIR__)
438 .  message - an error text string, usually just printed to the screen
439 .  number - the generic error number
440 .  p - PETSC_ERROR_INITIAL if error just detected, otherwise PETSC_ERROR_REPEAT
441 -  ctx - error handler context
442 
443    Options Database Keys:
444 .  -on_error_attach_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] - Activates
445    debugger attachment
446 
447    Level: developer
448 
449    Notes:
450    By default the GNU debugger, gdb, is used.  Alternatives are dbx and
451    xxgdb,xldb (on IBM rs6000), xdb (on HP-UX).
452 
453    Most users need not directly employ this routine and the other error
454    handlers, but can instead use the simplified interface SETERR, which has
455    the calling sequence
456 $     SETERRQ(PETSC_COMM_SELF,number,p,message)
457 
458    Notes for experienced users:
459    Use PetscPushErrorHandler() to set the desired error handler.  The
460    currently available PETSc error handlers are
461 $    PetscTraceBackErrorHandler()
462 $    PetscAttachDebuggerErrorHandler()
463 $    PetscAbortErrorHandler()
464    or you may write your own.
465 
466    Concepts: debugger^error handler
467    Concepts: error handler^attach debugger
468 
469 .seealso:  PetscPushErrorHandler(), PetscTraceBackErrorHandler(),
470            PetscAbortErrorHandler()
471 @*/
472 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)
473 {
474   PetscErrorCode ierr;
475 
476   PetscFunctionBegin;
477   if (!fun)  fun = "User provided function";
478   if (!dir)  dir = " ";
479   if (!mess) mess = " ";
480 
481   (*PetscErrorPrintf)("%s() line %d in %s%s %s\n",fun,line,dir,file,mess);
482 
483   ierr = PetscAttachDebugger();
484   if (ierr) { /* call abort because don't want to kill other MPI processes that may successfully attach to debugger */
485     abort();
486   }
487   PetscFunctionReturn(0);
488 }
489 
490 #undef __FUNCT__
491 #define __FUNCT__ "PetscStopForDebugger"
492 /*@C
493    PetscStopForDebugger - Prints a message to the screen indicating how to
494          attach to the process with the debugger and then waits for the
495          debugger to attach.
496 
497    Not Collective
498 
499    Level: advanced
500 
501    Developer Notes: Since this can be called by the error handler should it be calling SETERRQ() and CHKERRQ()?
502 
503    Concepts: debugger^waiting for attachment
504 
505 .seealso: PetscSetDebugger(), PetscAttachDebugger()
506 @*/
507 PetscErrorCode  PetscStopForDebugger(void)
508 {
509   PetscErrorCode ierr;
510   PetscInt       sleeptime=0;
511 #if !defined(PETSC_CANNOT_START_DEBUGGER)
512   int            ppid;
513   PetscMPIInt    rank;
514   char           program[PETSC_MAX_PATH_LEN],hostname[256];
515   PetscBool      isdbx,isxldb,isxxgdb,isddd,iskdbg,isups,isxdb;
516 #endif
517 
518   PetscFunctionBegin;
519 #if defined(PETSC_CANNOT_START_DEBUGGER)
520   (*PetscErrorPrintf)("System cannot start debugger; just continuing program\n");
521 #else
522   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
523   if (ierr) rank = 0; /* ignore error since this may be already in error handler */
524   ierr = PetscGetHostName(hostname,256);
525   if (ierr) {
526     (*PetscErrorPrintf)("Cannot determine hostname; just continuing program\n");
527     PetscFunctionReturn(0);
528   }
529 
530   ierr = PetscGetProgramName(program,256);
531   if (ierr) {
532     (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n");
533     PetscFunctionReturn(0);
534   }
535   if (!program[0]) {
536     (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n");
537     PetscFunctionReturn(0);
538   }
539 
540   ppid = getpid();
541 
542   ierr = PetscStrcmp(Debugger,"xxgdb",&isxxgdb);CHKERRQ(ierr);
543   ierr = PetscStrcmp(Debugger,"ddd",&isddd);CHKERRQ(ierr);
544   ierr = PetscStrcmp(Debugger,"kdbg",&iskdbg);CHKERRQ(ierr);
545   ierr = PetscStrcmp(Debugger,"ups",&isups);CHKERRQ(ierr);
546   ierr = PetscStrcmp(Debugger,"xldb",&isxldb);CHKERRQ(ierr);
547   ierr = PetscStrcmp(Debugger,"xdb",&isxdb);CHKERRQ(ierr);
548   ierr = PetscStrcmp(Debugger,"dbx",&isdbx);CHKERRQ(ierr);
549 
550   if (isxxgdb || isups || isddd || iskdbg ) {
551     (*PetscErrorPrintf)("[%d]%s>>%s %s %d\n",rank,hostname,Debugger,program,ppid);
552   }
553 #if defined(PETSC_USE_A_FOR_DEBUGGER)
554   else if (isxldb) {
555     (*PetscErrorPrintf)("{%d]%s>>%s -a %d %s\n",rank,hostname,Debugger,ppid,program);
556   }
557 #endif
558 #if defined(PETSC_USE_P_FOR_DEBUGGER)
559   else if (isdbx) {
560     (*PetscErrorPrintf)("[%d]%s>>%s -p %d %s\n",rank,hostname,Debugger,ppid,program);
561   }
562 #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER)
563   else if (isxdb) {
564     (*PetscErrorPrintf)("[%d]%s>>%s -l ALL -P %d %s\n",rank,hostname,Debugger,ppid,program);
565   }
566 #elif defined(PETSC_USE_A_FOR_DEBUGGER)
567   else if (isdbx) {
568     (*PetscErrorPrintf)("[%d]%s>>%s -a %d\n",rank,hostname,Debugger,ppid);
569   }
570 #elif defined(PETSC_USE_PID_FOR_DEBUGGER)
571   else if (isdbx) {
572     (*PetscErrorPrintf)("[%d]%s>>%s -pid %d %s\n",rank,hostname,Debugger,ppid,program);
573   }
574 #else
575   else {
576     (*PetscErrorPrintf)("[%d]%s>>%s %s %d\n",rank,hostname,Debugger,program,ppid);
577   }
578 #endif
579 #endif /* PETSC_CANNOT_START_DEBUGGER */
580 
581   fflush(stdout); /* ignore error because may already be in error handler */
582 
583   sleeptime = 25; /* default to sleep waiting for debugger */
584   PetscOptionsGetInt(PETSC_NULL,"-debugger_pause",&sleeptime,PETSC_NULL); /* ignore error because may already be in error handler */
585   if (sleeptime < 0) sleeptime = -sleeptime;
586 #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP)
587   /*
588       HP cannot attach process to sleeping debugger, hence count instead
589   */
590   {
591     PetscReal x = 1.0;
592     int i=10000000;
593     while (i--) x++ ; /* cannot attach to sleeper */
594   }
595 #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY)
596   /*
597       IBM sleep may return at anytime, hence must see if there is more time to sleep
598   */
599   {
600     int left = sleeptime;
601     while (left > 0) {left = sleep(left) - 1;}
602   }
603 #else
604   PetscSleep(sleeptime);
605 #endif
606   PetscFunctionReturn(0);
607 }
608 
609 
610 
611