xref: /petsc/src/sys/error/adebug.c (revision fa6b8e389e8051670ac35c373b6c9ca09b68ef1f)
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   PetscFunctionReturn(0);
97 }
98 
99 #undef __FUNCT__
100 #define __FUNCT__ "PetscSetDefaultDebugger"
101 /*@
102     PetscSetDefaultDebugger - Causes PETSc to use its default  debugger.
103 
104    Not collective
105 
106     Level: advanced
107 
108 .seealso: PetscSetDebugger(), PetscSetDebuggerFromString()
109 @*/
110 PetscErrorCode PETSC_DLLEXPORT PetscSetDefaultDebugger(void)
111 {
112   PetscErrorCode ierr;
113 
114   PetscFunctionBegin;
115 #if defined(PETSC_USE_DBX_DEBUGGER)
116   ierr = PetscSetDebugger("dbx",PETSC_TRUE);CHKERRQ(ierr);
117 #elif defined(PETSC_USE_XDB_DEBUGGER)
118   ierr = PetscSetDebugger("xdb",PETSC_TRUE);CHKERRQ(ierr);
119 #elif defined(PETSC_USE_IDB_DEBUGGER)
120   ierr = PetscSetDebugger("idb",PETSC_TRUE);CHKERRQ(ierr);
121 #else  /* Default is gdb */
122   ierr = PetscSetDebugger("gdb",PETSC_TRUE);CHKERRQ(ierr);
123 #endif
124   ierr = PetscSetDebugTerminal("xterm -e");CHKERRQ(ierr);
125   PetscFunctionReturn(0);
126 }
127 
128 #undef __FUNCT__
129 #define __FUNCT__ "PetscCheckDebugger_Private"
130 static PetscErrorCode PetscCheckDebugger_Private(const char defaultDbg[], const char string[], const char *debugger[])
131 {
132   PetscTruth     exists;
133   char           *f;
134   PetscErrorCode ierr;
135 
136   PetscFunctionBegin;
137   ierr = PetscStrstr(string, defaultDbg, &f);CHKERRQ(ierr);
138   if (f) {
139     ierr = PetscTestFile(string, 'x', &exists);CHKERRQ(ierr);
140     if (exists) {
141       *debugger = string;
142     } else {
143       *debugger = defaultDbg;
144     }
145   }
146   PetscFunctionReturn(0);
147 }
148 
149 #undef __FUNCT__
150 #define __FUNCT__ "PetscSetDebuggerFromString"
151 /*@C
152     PetscSetDebuggerFromString - Set the complete path for the
153        debugger for PETSc to use.
154 
155    Not collective
156 
157    Level: advanced
158 
159 .seealso: PetscSetDebugger(), PetscSetDefaultDebugger()
160 @*/
161 PetscErrorCode PETSC_DLLEXPORT PetscSetDebuggerFromString(char *string)
162 {
163   const char     *debugger = PETSC_NULL;
164   PetscTruth     xterm    = PETSC_TRUE;
165   char           *f;
166   PetscErrorCode ierr;
167 
168   PetscFunctionBegin;
169   ierr = PetscStrstr(string, "noxterm", &f);CHKERRQ(ierr);
170   if (f) xterm = PETSC_FALSE;
171   ierr = PetscStrstr(string, "ddd", &f);CHKERRQ(ierr);
172   if (f) xterm = PETSC_FALSE;
173   ierr = PetscCheckDebugger_Private("xdb",      string, &debugger);CHKERRQ(ierr);
174   ierr = PetscCheckDebugger_Private("dbx",      string, &debugger);CHKERRQ(ierr);
175   ierr = PetscCheckDebugger_Private("xldb",     string, &debugger);CHKERRQ(ierr);
176   ierr = PetscCheckDebugger_Private("gdb",      string, &debugger);CHKERRQ(ierr);
177   ierr = PetscCheckDebugger_Private("idb",      string, &debugger);CHKERRQ(ierr);
178   ierr = PetscCheckDebugger_Private("xxgdb",    string, &debugger);CHKERRQ(ierr);
179   ierr = PetscCheckDebugger_Private("ddd",      string, &debugger);CHKERRQ(ierr);
180   ierr = PetscCheckDebugger_Private("kdbg",     string, &debugger);CHKERRQ(ierr);
181   ierr = PetscCheckDebugger_Private("ups",      string, &debugger);CHKERRQ(ierr);
182   ierr = PetscCheckDebugger_Private("workshop", string, &debugger);CHKERRQ(ierr);
183   ierr = PetscCheckDebugger_Private("pgdbg",    string, &debugger);CHKERRQ(ierr);
184   ierr = PetscCheckDebugger_Private("pathdb",   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 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_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     PetscTruth isdbx,isidb,isxldb,isxxgdb,isups,isxdb,isworkshop,isddd,iskdbg;
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 
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         PetscTruth 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 defined(PETSC_USE_P_FOR_DEBUGGER)
336       if (isdbx) {
337         j = jj;
338         args[j++] = "-p";
339         args[j++] = pid;
340         args[j++] = program;
341         args[j++] = 0;
342       }
343 #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER)
344       if (isxdb) {
345         j = jj;
346         args[j++] = "-l";
347         args[j++] = "ALL";
348         args[j++] = "-P";
349         args[j++] = pid;
350         args[j++] = program;
351         args[j++] = 0;
352       }
353 #elif defined(PETSC_USE_A_FOR_DEBUGGER)
354       if (isdbx) {
355         j = jj;
356         args[j++] = "-a";
357         args[j++] = pid;
358         args[j++] = 0;
359       }
360 #elif defined(PETSC_USE_PID_FOR_DEBUGGER)
361       if (isdbx) {
362         j = jj;
363         args[j++] = "-pid";
364         args[j++] = pid;
365         args[j++] = program;
366         args[j++] = 0;
367       }
368 #endif
369       if (Xterm) {
370         if (display[0]) {
371           (*PetscErrorPrintf)("PETSC: Attaching %s to %s of pid %s on display %s on machine %s\n",Debugger,program,pid,display,hostname);
372         } else {
373           (*PetscErrorPrintf)("PETSC: Attaching %s to %s on pid %s on %s\n",Debugger,program,pid,hostname);
374         }
375         if (execvp(args[0],(char**)args)  < 0) {
376           perror("Unable to start debugger in xterm");
377           exit(0);
378         }
379       } else {
380         (*PetscErrorPrintf)("PETSC: Attaching %s to %s of pid %s on %s\n",Debugger,program,pid,hostname);
381         if (execvp(args[0],(char**)args)  < 0) {
382           perror("Unable to start debugger");
383           exit(0);
384         }
385       }
386     }
387   } else {   /* I am the child, continue with user code */
388     sleeptime = 10; /* default to sleep waiting for debugger */
389     ierr = PetscOptionsGetReal(PETSC_NULL,"-debugger_pause",&sleeptime,PETSC_NULL);CHKERRQ(ierr);
390     if (sleeptime < 0) sleeptime = -sleeptime;
391 #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP)
392     /*
393         HP cannot attach process to sleeping debugger, hence count instead
394     */
395     {
396       PetscReal x = 1.0;
397       int i=10000000;
398       while (i--) x++ ; /* cannot attach to sleeper */
399     }
400 #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY)
401     /*
402         IBM sleep may return at anytime, hence must see if there is more time to sleep
403     */
404     {
405       int left = sleeptime;
406       while (left > 0) {left = PetscSleep(left) - 1;}
407     }
408 #else
409     PetscSleep(sleeptime);
410 #endif
411   }
412 #endif
413   PetscFunctionReturn(0);
414 }
415 
416 #undef __FUNCT__
417 #define __FUNCT__ "PetscAttachDebuggerErrorHandler"
418 /*@C
419    PetscAttachDebuggerErrorHandler - Error handler that attaches
420    a debugger to a running process when an error is detected.
421    This routine is useful for examining variables, etc.
422 
423    Not Collective
424 
425    Input Parameters:
426 +  comm - communicator over which error occurred
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 - PETSC_ERROR_INITIAL if error just detected, otherwise PETSC_ERROR_REPEAT
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(PETSC_COMM_SELF,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(MPI_Comm comm,int line,const char* fun,const char *file,const char* dir,PetscErrorCode num,PetscErrorType 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) { /* call abort because don't want to kill other MPI processes that may successfully attach to debugger */
478     abort();
479   }
480   PetscFunctionReturn(0);
481 }
482 
483 #undef __FUNCT__
484 #define __FUNCT__ "PetscStopForDebugger"
485 /*@C
486    PetscStopForDebugger - Prints a message to the screen indicating how to
487          attach to the process with the debugger and then waits for the
488          debugger to attach.
489 
490    Not Collective
491 
492    Level: advanced
493 
494    Developer Notes: Since this can be called by the error handler should it be calling SETERRQ() and CHKERRQ()?
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 #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   if (ierr) rank = 0; /* ignore error since this may be already in error handler */
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   fflush(stdout); /* ignore error because may already be in error handler */
575 
576   sleeptime = 25; /* default to sleep waiting for debugger */
577   PetscOptionsGetInt(PETSC_NULL,"-debugger_pause",&sleeptime,PETSC_NULL); /* ignore error because may already be in error handler */
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