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