xref: /petsc/src/sys/error/adebug.c (revision 40badf4fbc550ac1f60bd080eaff6de6d55b946d)
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 
11 /*
12       These are the debugger and display used if the debugger is started up
13 */
14 static char      PetscDebugger[PETSC_MAX_PATH_LEN];
15 static char      DebugTerminal[PETSC_MAX_PATH_LEN];
16 static PetscBool UseDebugTerminal = PETSC_TRUE;
17 PetscBool        petscwaitonerrorflg = PETSC_FALSE;
18 PetscBool        petscindebugger  = PETSC_FALSE;
19 
20 /*@C
21    PetscSetDebugTerminal - Sets the terminal to use for debugging.
22 
23    Not Collective
24 
25    Input Parameters:
26 .  terminal - name of terminal and any flags required to execute a program.
27               For example xterm, "urxvt -e", "gnome-terminal -x".
28               On Apple MacOS you can use Terminal (note the capital T)
29 
30    Options Database Keys:
31    -debug_terminal terminal - use this terminal instead of the default
32 
33    Level: developer
34 
35    Notes:
36    You can start the debugger for all processes in the same GNU screen session.
37 
38      mpiexec -n 4 ./myapp -start_in_debugger -debug_terminal "screen -X -S debug screen"
39 
40    will open 4 windows in the session named "debug".
41 
42    The default on Apple is Terminal, on other systems the default is xterm
43 
44    Fortran Note:
45    This routine is not supported in Fortran.
46 
47 .seealso: PetscSetDebugger()
48 @*/
49 PetscErrorCode PetscSetDebugTerminal(const char terminal[])
50 {
51   PetscBool xterm;
52 
53   PetscFunctionBegin;
54   CHKERRQ(PetscStrncpy(DebugTerminal,terminal,sizeof(DebugTerminal)));
55   CHKERRQ(PetscStrcmp(terminal,"xterm",&xterm));
56   if (xterm) CHKERRQ(PetscStrlcat(DebugTerminal," -e",sizeof(DebugTerminal)));
57   PetscFunctionReturn(0);
58 }
59 
60 /*@C
61    PetscSetDebugger - Sets options associated with the debugger.
62 
63    Not Collective
64 
65    Input Parameters:
66 +  debugger - name of debugger, which should be in your path,
67               usually "lldb", "dbx", "gdb", "cuda-gdb", "idb", "xxgdb", "kdgb" or "ddd". Also, HP-UX
68               supports "xdb", and IBM rs6000 supports "xldb".
69 
70 -  usedebugterminal - flag to indicate debugger window, set to either PETSC_TRUE (to indicate
71             debugger should be started in a new terminal window) or PETSC_FALSE (to start debugger
72             in initial window (the option PETSC_FALSE makes no sense when using more
73             than one MPI process.)
74 
75    Level: developer
76 
77    Fortran Note:
78    This routine is not supported in Fortran.
79 
80 .seealso: PetscAttachDebugger(), PetscAttachDebuggerErrorHandler(), PetscSetDebugTerminal()
81 @*/
82 PetscErrorCode PetscSetDebugger(const char debugger[], PetscBool usedebugterminal)
83 {
84   PetscFunctionBegin;
85   if (debugger) CHKERRQ(PetscStrncpy(PetscDebugger,debugger,sizeof(PetscDebugger)));
86   if (UseDebugTerminal) UseDebugTerminal = usedebugterminal;
87   PetscFunctionReturn(0);
88 }
89 
90 /*@C
91     PetscSetDefaultDebugger - Causes PETSc to use its default debugger and output terminal
92 
93    Not collective
94 
95     Level: developer
96 
97 .seealso: PetscSetDebugger(), PetscSetDebuggerFromString()
98 @*/
99 PetscErrorCode PetscSetDefaultDebugger(void)
100 {
101   PetscFunctionBegin;
102 #if defined(PETSC_USE_DEBUGGER)
103   CHKERRQ(PetscSetDebugger(PETSC_USE_DEBUGGER,PETSC_TRUE));
104 #endif
105 #if defined(__APPLE__)
106   CHKERRQ(PetscSetDebugTerminal("Terminal"));
107 #else
108   CHKERRQ(PetscSetDebugTerminal("xterm"));
109 #endif
110   PetscFunctionReturn(0);
111 }
112 
113 static PetscErrorCode PetscCheckDebugger_Private(const char defaultDbg[], const char string[], const char *debugger[])
114 {
115   PetscBool  exists;
116   char      *f;
117 
118   PetscFunctionBegin;
119   CHKERRQ(PetscStrstr(string, defaultDbg, &f));
120   if (f) {
121     CHKERRQ(PetscTestFile(string, 'x', &exists));
122     if (exists) *debugger = string;
123     else        *debugger = defaultDbg;
124   }
125   PetscFunctionReturn(0);
126 }
127 
128 /*@C
129     PetscSetDebuggerFromString - Set the complete path for the
130        debugger for PETSc to use.
131 
132    Not collective
133 
134    Level: developer
135 
136 .seealso: PetscSetDebugger(), PetscSetDefaultDebugger()
137 @*/
138 PetscErrorCode  PetscSetDebuggerFromString(const char *string)
139 {
140   const char *debugger    = NULL;
141   PetscBool   useterminal = PETSC_TRUE;
142   char       *f;
143 
144   PetscFunctionBegin;
145   CHKERRQ(PetscStrstr(string, "noxterm", &f));
146   if (f) useterminal = PETSC_FALSE;
147   CHKERRQ(PetscStrstr(string, "ddd", &f));
148   if (f) useterminal = PETSC_FALSE;
149   CHKERRQ(PetscStrstr(string, "noterminal", &f));
150   if (f) useterminal = PETSC_FALSE;
151   CHKERRQ(PetscCheckDebugger_Private("xdb",      string, &debugger));
152   CHKERRQ(PetscCheckDebugger_Private("dbx",      string, &debugger));
153   CHKERRQ(PetscCheckDebugger_Private("xldb",     string, &debugger));
154   CHKERRQ(PetscCheckDebugger_Private("gdb",      string, &debugger));
155   CHKERRQ(PetscCheckDebugger_Private("cuda-gdb", string, &debugger));
156   CHKERRQ(PetscCheckDebugger_Private("idb",      string, &debugger));
157   CHKERRQ(PetscCheckDebugger_Private("xxgdb",    string, &debugger));
158   CHKERRQ(PetscCheckDebugger_Private("ddd",      string, &debugger));
159   CHKERRQ(PetscCheckDebugger_Private("kdbg",     string, &debugger));
160   CHKERRQ(PetscCheckDebugger_Private("ups",      string, &debugger));
161   CHKERRQ(PetscCheckDebugger_Private("workshop", string, &debugger));
162   CHKERRQ(PetscCheckDebugger_Private("pgdbg",    string, &debugger));
163   CHKERRQ(PetscCheckDebugger_Private("pathdb",   string, &debugger));
164   CHKERRQ(PetscCheckDebugger_Private("lldb",     string, &debugger));
165   CHKERRQ(PetscSetDebugger(debugger, useterminal));
166   PetscFunctionReturn(0);
167 }
168 
169 /*@
170    PetscWaitOnError - If an error is detected and the process would normally exit the main program with MPI_Abort() sleep instead
171                       of exiting.
172 
173    Not Collective
174 
175    Level: advanced
176 
177    Notes:
178       When -start_in_debugger -debugger_ranks x,y,z is used this prevents the processes NOT listed in x,y,z from calling MPI_Abort and
179       killing the user's debugging sessions.
180 
181 .seealso: PetscSetDebugger(), PetscAttachDebugger()
182 @*/
183 PetscErrorCode  PetscWaitOnError()
184 {
185   petscwaitonerrorflg  = PETSC_TRUE;
186   return 0;
187 }
188 
189 /*@
190    PetscAttachDebugger - Attaches the debugger to the running process.
191 
192    Not Collective
193 
194    Options Database Keys:
195 -  -start_in_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] [-debugger_ranks m,n] -debug_terminal xterm or Terminal (for Apple)
196 .  -on_error_attach_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] - Activates debugger attachment
197 
198    Level: advanced
199 
200    Developer Notes:
201     Since this can be called by the error handler should it be calling SETERRQ() and CHKERRQ()?
202 
203 .seealso: PetscSetDebugger(), PetscSetDefaultDebugger(), PetscSetDebugTerminal(), PetscAttachDebuggerErrorHandler(), PetscStopForDebugger()
204 @*/
205 PetscErrorCode PetscAttachDebugger(void)
206 {
207 #if !defined(PETSC_CANNOT_START_DEBUGGER) && defined(PETSC_HAVE_FORK)
208   int            child    =0;
209   PetscReal      sleeptime=0;
210   PetscErrorCode ierr;
211   char           program[PETSC_MAX_PATH_LEN],display[256],hostname[64];
212 #endif
213 
214   PetscFunctionBegin;
215 #if defined(PETSC_CANNOT_START_DEBUGGER) || !defined(PETSC_HAVE_FORK)
216   (*PetscErrorPrintf)("System cannot start debugger\n");
217   (*PetscErrorPrintf)("On Cray run program in Totalview debugger\n");
218   (*PetscErrorPrintf)("On Windows use Developer Studio(MSDEV)\n");
219   PETSCABORT(PETSC_COMM_WORLD,PETSC_ERR_SUP_SYS);
220 #else
221   ierr = PetscGetDisplay(display,sizeof(display));
222   if (PetscUnlikely(ierr)) {
223     (*PetscErrorPrintf)("Cannot determine display\n");
224     PetscFunctionReturn(PETSC_ERR_SYS);
225   }
226   CHKERRQ(PetscGetProgramName(program,sizeof(program)));
227   if (PetscUnlikely(ierr)) {
228     (*PetscErrorPrintf)("Cannot determine program name\n");
229     PetscFunctionReturn(PETSC_ERR_SYS);
230   }
231   if (PetscUnlikely(!program[0])) {
232     (*PetscErrorPrintf)("Cannot determine program name\n");
233     PetscFunctionReturn(PETSC_ERR_SYS);
234   }
235   child = (int)fork();
236   if (PetscUnlikely(child < 0)) {
237     (*PetscErrorPrintf)("Error in fork() prior to attaching debugger\n");
238     PetscFunctionReturn(PETSC_ERR_SYS);
239   }
240   petscindebugger = PETSC_TRUE;
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 !defined(PETSC_DO_NOT_SWAP_CHILD_FOR_DEBUGGER)
247   if (child) child = 0;
248   else       child = (int)getppid();
249 #endif
250 
251   if (child) { /* I am the parent, will run the debugger */
252     const char *args[10];
253     char       pid[10];
254     PetscInt   j,jj;
255     PetscBool  isdbx,isidb,isxldb,isxxgdb,isups,isxdb,isworkshop,isddd,iskdbg,islldb;
256 
257     CHKERRQ(PetscGetHostName(hostname,sizeof(hostname)));
258     /*
259          We need to send a continue signal to the "child" process on the
260        alpha, otherwise it just stays off forever
261     */
262 #if defined(PETSC_NEED_KILL_FOR_DEBUGGER)
263     kill(child,SIGCONT);
264 #endif
265     sprintf(pid,"%d",child);
266 
267     CHKERRQ(PetscStrcmp(PetscDebugger,"xxgdb",&isxxgdb));
268     CHKERRQ(PetscStrcmp(PetscDebugger,"ddd",&isddd));
269     CHKERRQ(PetscStrcmp(PetscDebugger,"kdbg",&iskdbg));
270     CHKERRQ(PetscStrcmp(PetscDebugger,"ups",&isups));
271     CHKERRQ(PetscStrcmp(PetscDebugger,"xldb",&isxldb));
272     CHKERRQ(PetscStrcmp(PetscDebugger,"xdb",&isxdb));
273     CHKERRQ(PetscStrcmp(PetscDebugger,"dbx",&isdbx));
274     CHKERRQ(PetscStrcmp(PetscDebugger,"idb",&isidb));
275     CHKERRQ(PetscStrcmp(PetscDebugger,"workshop",&isworkshop));
276     CHKERRQ(PetscStrcmp(PetscDebugger,"lldb",&islldb));
277 
278     if (isxxgdb || isups || isddd) {
279       args[1] = program; args[2] = pid; args[3] = "-display";
280       args[0] = PetscDebugger; args[4] = display; args[5] = NULL;
281       printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname);
282       if (execvp(args[0],(char**)args)  < 0) {
283         perror("Unable to start debugger");
284         exit(0);
285       }
286     } else if (iskdbg) {
287       args[1] = "-p"; args[2] = pid; args[3] = program;  args[4] = "-display";
288       args[0] = PetscDebugger; args[5] = display; args[6] = NULL;
289       printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[3],pid,hostname);
290       if (execvp(args[0],(char**)args)  < 0) {
291         perror("Unable to start debugger");
292         exit(0);
293       }
294     } else if (isxldb) {
295       args[1] = "-a"; args[2] = pid; args[3] = program;  args[4] = "-display";
296       args[0] = PetscDebugger; args[5] = display; args[6] = NULL;
297       printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname);
298       if (execvp(args[0],(char**)args)  < 0) {
299         perror("Unable to start debugger");
300         exit(0);
301       }
302     } else if (isworkshop) {
303       args[1] = "-s"; args[2] = pid; args[3] = "-D"; args[4] = "-";
304       args[0] = PetscDebugger; args[5] = pid; args[6] = "-display"; args[7] = display; args[8] = NULL;
305       printf("PETSC: Attaching %s to %s on %s\n",args[0],pid,hostname);
306       if (execvp(args[0],(char**)args)  < 0) {
307         perror("Unable to start debugger");
308         exit(0);
309       }
310     } else {
311       j = 0;
312       if (UseDebugTerminal) {
313         PetscBool cmp;
314         char      *tmp,*tmp1;
315         CHKERRQ(PetscStrncmp(DebugTerminal,"Terminal",8,&cmp));
316         if (cmp) {
317           char command[1024];
318           CHKERRQ(PetscSNPrintf(command,sizeof(command),"osascript -e 'tell app \"Terminal\" to do script \"lldb  -p %s  %s \"'\n",pid,program));
319           CHKERRQ(PetscPOpen(PETSC_COMM_SELF,NULL,command,"r",NULL));
320           exit(0);
321         }
322 
323         CHKERRQ(PetscStrncmp(DebugTerminal,"screen",6,&cmp));
324         if (!cmp) CHKERRQ(PetscStrncmp(DebugTerminal,"gnome-terminal",6,&cmp));
325         if (cmp) display[0] = 0; /* when using screen, we never pass -display */
326         args[j++] = tmp = DebugTerminal;
327         if (display[0]) {
328           args[j++] = "-display"; args[j++] = display;
329         }
330         while (*tmp) {
331           CHKERRQ(PetscStrchr(tmp,' ',&tmp1));
332           if (!tmp1) break;
333           *tmp1     = 0;
334           tmp       = tmp1+1;
335           args[j++] = tmp;
336         }
337       }
338       args[j++] = PetscDebugger;
339       jj = j;
340       /* this is for default gdb */
341       args[j++] = program;
342       args[j++] = pid;
343       args[j++] = NULL;
344 
345       if (isidb) {
346         j = jj;
347         args[j++] = "-pid";
348         args[j++] = pid;
349         args[j++] = "-gdb";
350         args[j++] = program;
351         args[j++] = NULL;
352       }
353       if (islldb) {
354         j = jj;
355         args[j++] = "-p";
356         args[j++] = pid;
357         args[j++] = NULL;
358       }
359       if (isdbx) {
360         j = jj;
361 #if defined(PETSC_USE_P_FOR_DEBUGGER)
362         args[j++] = "-p";
363         args[j++] = pid;
364         args[j++] = program;
365 #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER)
366         args[j++] = "-l";
367         args[j++] = "ALL";
368         args[j++] = "-P";
369         args[j++] = pid;
370         args[j++] = program;
371 #elif defined(PETSC_USE_A_FOR_DEBUGGER)
372         args[j++] = "-a";
373         args[j++] = pid;
374 #elif defined(PETSC_USE_PID_FOR_DEBUGGER)
375         args[j++] = "-pid";
376         args[j++] = pid;
377         args[j++] = program;
378 #else
379         args[j++] = program;
380         args[j++] = pid;
381 #endif
382         args[j++] = NULL;
383       }
384       if (UseDebugTerminal) {
385         if (display[0]) printf("PETSC: Attaching %s to %s of pid %s on display %s on machine %s\n",PetscDebugger,program,pid,display,hostname);
386         else            printf("PETSC: Attaching %s to %s on pid %s on %s\n",PetscDebugger,program,pid,hostname);
387 
388         if (execvp(args[0],(char**)args)  < 0) {
389           perror("Unable to start debugger in xterm");
390           exit(0);
391         }
392       } else {
393         printf("PETSC: Attaching %s to %s of pid %s on %s\n",PetscDebugger,program,pid,hostname);
394         if (execvp(args[0],(char**)args)  < 0) {
395           perror("Unable to start debugger");
396           exit(0);
397         }
398       }
399     }
400   } else {   /* I am the child, continue with user code */
401     sleeptime = 10; /* default to sleep waiting for debugger */
402     CHKERRQ(PetscOptionsGetReal(NULL,NULL,"-debugger_pause",&sleeptime,NULL));
403     if (sleeptime < 0) sleeptime = -sleeptime;
404 #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP)
405     /*
406         HP cannot attach process to sleeping debugger, hence count instead
407     */
408     {
409       PetscReal x = 1.0;
410       int       i =10000000;
411       while (i--) x++;  /* cannot attach to sleeper */
412     }
413 #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY)
414     /*
415         IBM sleep may return at anytime, hence must see if there is more time to sleep
416     */
417     {
418       int left = sleeptime;
419       while (left > 0) left = PetscSleep(left) - 1;
420     }
421 #else
422     PetscSleep(sleeptime);
423 #endif
424   }
425 #endif
426   PetscFunctionReturn(0);
427 }
428 
429 /*@C
430    PetscAttachDebuggerErrorHandler - Error handler that attaches
431    a debugger to a running process when an error is detected.
432    This routine is useful for examining variables, etc.
433 
434    Not Collective
435 
436    Input Parameters:
437 +  comm - communicator over which error occurred
438 .  line - the line number of the error (indicated by __LINE__)
439 .  file - the file in which the error was detected (indicated by __FILE__)
440 .  message - an error text string, usually just printed to the screen
441 .  number - the generic error number
442 .  p - PETSC_ERROR_INITIAL if error just detected, otherwise PETSC_ERROR_REPEAT
443 -  ctx - error handler context
444 
445    Options Database Keys:
446 +  -on_error_attach_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] - Activates debugger attachment
447 -  -start_in_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] [-debugger_ranks m,n]
448 
449    Level: developer
450 
451    Notes:
452    By default the GNU debugger, gdb, is used.  Alternatives are cuda-gdb, lldb, dbx and
453    xxgdb,xldb (on IBM rs6000), xdb (on HP-UX).
454 
455    Most users need not directly employ this routine and the other error
456    handlers, but can instead use the simplified interface SETERR, which has
457    the calling sequence
458 $     SETERRQ(PETSC_COMM_SELF,number,p,message)
459 
460    Notes for experienced users:
461    Use PetscPushErrorHandler() to set the desired error handler.  The
462    currently available PETSc error handlers are
463 $    PetscTraceBackErrorHandler()
464 $    PetscAttachDebuggerErrorHandler()
465 $    PetscAbortErrorHandler()
466    or you may write your own.
467 
468 .seealso:  PetscSetDebuggerFromString(), PetscSetDebugger(), PetscSetDefaultDebugger(), PetscError(), PetscPushErrorHandler(), PetscPopErrorHandler(), PetscTraceBackErrorHandler(),
469            PetscAbortErrorHandler(), PetscMPIAbortErrorHandler(), PetscEmacsClientErrorHandler(), PetscReturnErrorHandler(), PetscSetDebugTermainal()
470 @*/
471 PetscErrorCode  PetscAttachDebuggerErrorHandler(MPI_Comm comm,int line,const char *fun,const char *file,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 (!mess) mess = " ";
478 
479   (*PetscErrorPrintf)("%s() at %s:%d %s\n",fun,file,line,mess);
480 
481   ierr = PetscAttachDebugger();
482   if (ierr) abort(); /* call abort because don't want to kill other MPI processes that may successfully attach to debugger */
483   PetscFunctionReturn(0);
484 }
485 
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    Options Database:
494 .   -stop_for_debugger - will stop for you to attach the debugger when PetscInitialize() is called
495 
496    Level: developer
497 
498    Notes:
499     This is likely never needed since PetscAttachDebugger() is easier to use and seems to always work.
500 
501    Developer Notes:
502     Since this can be called by the error handler, should it be calling SETERRQ() and CHKERRQ()?
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,islldb;
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,sizeof(hostname));
524   if (ierr) {
525     (*PetscErrorPrintf)("Cannot determine hostname; just continuing program\n");
526     PetscFunctionReturn(0);
527   }
528 
529   ierr = PetscGetProgramName(program,sizeof(program));
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   CHKERRQ(PetscStrcmp(PetscDebugger,"xxgdb",&isxxgdb));
542   CHKERRQ(PetscStrcmp(PetscDebugger,"ddd",&isddd));
543   CHKERRQ(PetscStrcmp(PetscDebugger,"kdbg",&iskdbg));
544   CHKERRQ(PetscStrcmp(PetscDebugger,"ups",&isups));
545   CHKERRQ(PetscStrcmp(PetscDebugger,"xldb",&isxldb));
546   CHKERRQ(PetscStrcmp(PetscDebugger,"xdb",&isxdb));
547   CHKERRQ(PetscStrcmp(PetscDebugger,"dbx",&isdbx));
548   CHKERRQ(PetscStrcmp(PetscDebugger,"lldb",&islldb));
549 
550   if (isxxgdb || isups || isddd || iskdbg) printf("[%d]%s>>%s %s %d\n",rank,hostname,PetscDebugger,program,ppid);
551   else if (isxldb) printf("[%d]%s>>%s -a %d %s\n",rank,hostname,PetscDebugger,ppid,program);
552   else if (islldb) printf("[%d]%s>>%s -p %d\n",rank,hostname,PetscDebugger,ppid);
553   else if (isdbx) {
554 #if defined(PETSC_USE_P_FOR_DEBUGGER)
555      printf("[%d]%s>>%s -p %d %s\n",rank,hostname,PetscDebugger,ppid,program);
556 #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER)
557      printf("[%d]%s>>%s -l ALL -P %d %s\n",rank,hostname,PetscDebugger,ppid,program);
558 #elif defined(PETSC_USE_A_FOR_DEBUGGER)
559      printf("[%d]%s>>%s -a %d\n",rank,hostname,PetscDebugger,ppid);
560 #elif defined(PETSC_USE_PID_FOR_DEBUGGER)
561      printf("[%d]%s>>%s -pid %d %s\n",rank,hostname,PetscDebugger,ppid,program);
562 #else
563      printf("[%d]%s>>%s %s %d\n",rank,hostname,PetscDebugger,program,ppid);
564 #endif
565   }
566 #endif /* PETSC_CANNOT_START_DEBUGGER */
567 
568   fflush(stdout); /* ignore error because may already be in error handler */
569 
570   sleeptime = 25; /* default to sleep waiting for debugger */
571   PetscOptionsGetInt(NULL,NULL,"-debugger_pause",&sleeptime,NULL); /* ignore error because may already be in error handler */
572   if (sleeptime < 0) sleeptime = -sleeptime;
573 #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP)
574   /*
575       HP cannot attach process to sleeping debugger, hence count instead
576   */
577   {
578     PetscReal x = 1.0;
579     int       i =10000000;
580     while (i--) x++;  /* cannot attach to sleeper */
581   }
582 #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY)
583   /*
584       IBM sleep may return at anytime, hence must see if there is more time to sleep
585   */
586   {
587     int left = sleeptime;
588     while (left > 0) left = sleep(left) - 1;
589   }
590 #else
591   PetscSleep(sleeptime);
592 #endif
593   PetscFunctionReturn(0);
594 }
595