xref: /petsc/src/sys/error/adebug.c (revision af2269012df9f78a2e64b5a712f72d93507752c9)
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   PetscCall(PetscStrncpy(DebugTerminal,terminal,sizeof(DebugTerminal)));
55   PetscCall(PetscStrcmp(terminal,"xterm",&xterm));
56   if (xterm) PetscCall(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) PetscCall(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   PetscCall(PetscSetDebugger(PETSC_USE_DEBUGGER,PETSC_TRUE));
104 #endif
105 #if defined(__APPLE__)
106   PetscCall(PetscSetDebugTerminal("Terminal"));
107 #else
108   PetscCall(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   PetscCall(PetscStrstr(string, defaultDbg, &f));
120   if (f) {
121     PetscCall(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   PetscCall(PetscStrstr(string, "noxterm", &f));
146   if (f) useterminal = PETSC_FALSE;
147   PetscCall(PetscStrstr(string, "ddd", &f));
148   if (f) useterminal = PETSC_FALSE;
149   PetscCall(PetscStrstr(string, "noterminal", &f));
150   if (f) useterminal = PETSC_FALSE;
151   PetscCall(PetscCheckDebugger_Private("xdb",      string, &debugger));
152   PetscCall(PetscCheckDebugger_Private("dbx",      string, &debugger));
153   PetscCall(PetscCheckDebugger_Private("xldb",     string, &debugger));
154   PetscCall(PetscCheckDebugger_Private("gdb",      string, &debugger));
155   PetscCall(PetscCheckDebugger_Private("cuda-gdb", string, &debugger));
156   PetscCall(PetscCheckDebugger_Private("idb",      string, &debugger));
157   PetscCall(PetscCheckDebugger_Private("xxgdb",    string, &debugger));
158   PetscCall(PetscCheckDebugger_Private("ddd",      string, &debugger));
159   PetscCall(PetscCheckDebugger_Private("kdbg",     string, &debugger));
160   PetscCall(PetscCheckDebugger_Private("ups",      string, &debugger));
161   PetscCall(PetscCheckDebugger_Private("workshop", string, &debugger));
162   PetscCall(PetscCheckDebugger_Private("pgdbg",    string, &debugger));
163   PetscCall(PetscCheckDebugger_Private("pathdb",   string, &debugger));
164   PetscCall(PetscCheckDebugger_Private("lldb",     string, &debugger));
165   PetscCall(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 PetscCall()?
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   char      program[PETSC_MAX_PATH_LEN],display[256],hostname[64];
211 #endif
212 
213   PetscFunctionBegin;
214 #if defined(PETSC_CANNOT_START_DEBUGGER) || !defined(PETSC_HAVE_FORK)
215   (*PetscErrorPrintf)("System cannot start debugger\n");
216   (*PetscErrorPrintf)("On Cray run program in Totalview debugger\n");
217   (*PetscErrorPrintf)("On Windows use Developer Studio(MSDEV)\n");
218   PETSCABORT(PETSC_COMM_WORLD,PETSC_ERR_SUP_SYS);
219 #else
220   if (PetscUnlikely(PetscGetDisplay(display,sizeof(display)))) {
221     (*PetscErrorPrintf)("Cannot determine display\n");
222     PetscFunctionReturn(PETSC_ERR_SYS);
223   }
224   if (PetscUnlikely(PetscGetProgramName(program,sizeof(program)))) {
225     (*PetscErrorPrintf)("Cannot determine program name\n");
226     PetscFunctionReturn(PETSC_ERR_SYS);
227   }
228   if (PetscUnlikely(!program[0])) {
229     (*PetscErrorPrintf)("Cannot determine program name\n");
230     PetscFunctionReturn(PETSC_ERR_SYS);
231   }
232   child = (int)fork();
233   if (PetscUnlikely(child < 0)) {
234     (*PetscErrorPrintf)("Error in fork() prior to attaching debugger\n");
235     PetscFunctionReturn(PETSC_ERR_SYS);
236   }
237   petscindebugger = PETSC_TRUE;
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 !defined(PETSC_DO_NOT_SWAP_CHILD_FOR_DEBUGGER)
244   child = child ? 0 : (int)getppid();
245 #endif
246 
247   if (child) { /* I am the parent, will run the debugger */
248     const char *args[10];
249     char       pid[10];
250     PetscInt   j,jj;
251     PetscBool  isdbx,isidb,isxldb,isxxgdb,isups,isxdb,isworkshop,isddd,iskdbg,islldb;
252 
253     PetscCall(PetscGetHostName(hostname,sizeof(hostname)));
254     /*
255          We need to send a continue signal to the "child" process on the
256        alpha, otherwise it just stays off forever
257     */
258 #if defined(PETSC_NEED_KILL_FOR_DEBUGGER)
259     kill(child,SIGCONT);
260 #endif
261     sprintf(pid,"%d",child);
262 
263     PetscCall(PetscStrcmp(PetscDebugger,"xxgdb",&isxxgdb));
264     PetscCall(PetscStrcmp(PetscDebugger,"ddd",&isddd));
265     PetscCall(PetscStrcmp(PetscDebugger,"kdbg",&iskdbg));
266     PetscCall(PetscStrcmp(PetscDebugger,"ups",&isups));
267     PetscCall(PetscStrcmp(PetscDebugger,"xldb",&isxldb));
268     PetscCall(PetscStrcmp(PetscDebugger,"xdb",&isxdb));
269     PetscCall(PetscStrcmp(PetscDebugger,"dbx",&isdbx));
270     PetscCall(PetscStrcmp(PetscDebugger,"idb",&isidb));
271     PetscCall(PetscStrcmp(PetscDebugger,"workshop",&isworkshop));
272     PetscCall(PetscStrcmp(PetscDebugger,"lldb",&islldb));
273 
274     if (isxxgdb || isups || isddd) {
275       args[1] = program; args[2] = pid; args[3] = "-display";
276       args[0] = PetscDebugger; args[4] = display; args[5] = NULL;
277       printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname);
278       if (execvp(args[0],(char**)args)  < 0) {
279         perror("Unable to start debugger");
280         exit(0);
281       }
282     } else if (iskdbg) {
283       args[1] = "-p"; args[2] = pid; args[3] = program;  args[4] = "-display";
284       args[0] = PetscDebugger; args[5] = display; args[6] = NULL;
285       printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[3],pid,hostname);
286       if (execvp(args[0],(char**)args)  < 0) {
287         perror("Unable to start debugger");
288         exit(0);
289       }
290     } else if (isxldb) {
291       args[1] = "-a"; args[2] = pid; args[3] = program;  args[4] = "-display";
292       args[0] = PetscDebugger; args[5] = display; args[6] = NULL;
293       printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname);
294       if (execvp(args[0],(char**)args)  < 0) {
295         perror("Unable to start debugger");
296         exit(0);
297       }
298     } else if (isworkshop) {
299       args[1] = "-s"; args[2] = pid; args[3] = "-D"; args[4] = "-";
300       args[0] = PetscDebugger; args[5] = pid; args[6] = "-display"; args[7] = display; args[8] = NULL;
301       printf("PETSC: Attaching %s to %s on %s\n",args[0],pid,hostname);
302       if (execvp(args[0],(char**)args)  < 0) {
303         perror("Unable to start debugger");
304         exit(0);
305       }
306     } else {
307       j = 0;
308       if (UseDebugTerminal) {
309         PetscBool cmp;
310         char      *tmp,*tmp1;
311         PetscCall(PetscStrncmp(DebugTerminal,"Terminal",8,&cmp));
312         if (cmp) {
313           char command[1024];
314           if (islldb) PetscCall(PetscSNPrintf(command,sizeof(command),"osascript -e 'tell app \"Terminal\" to do script \"lldb  -p %s \"'\n",pid));
315           else {
316             char fullprogram[PETSC_MAX_PATH_LEN];
317             PetscCall(PetscGetFullPath(program,fullprogram,sizeof(fullprogram)));
318             PetscCall(PetscSNPrintf(command,sizeof(command),"osascript -e 'tell app \"Terminal\" to do script \"%s  %s %s \"'\n",PetscDebugger,fullprogram,pid));
319           }
320           PetscCall(PetscPOpen(PETSC_COMM_SELF,NULL,command,"r",NULL));
321           exit(0);
322         }
323 
324         PetscCall(PetscStrncmp(DebugTerminal,"screen",6,&cmp));
325         if (!cmp) PetscCall(PetscStrncmp(DebugTerminal,"gnome-terminal",6,&cmp));
326         if (cmp) display[0] = 0; /* when using screen, we never pass -display */
327         args[j++] = tmp = DebugTerminal;
328         if (display[0]) {
329           args[j++] = "-display"; args[j++] = display;
330         }
331         while (*tmp) {
332           PetscCall(PetscStrchr(tmp,' ',&tmp1));
333           if (!tmp1) break;
334           *tmp1     = 0;
335           tmp       = tmp1+1;
336           args[j++] = tmp;
337         }
338       }
339       args[j++] = PetscDebugger;
340       jj = j;
341       /* this is for default gdb */
342       args[j++] = program;
343       args[j++] = pid;
344       args[j++] = NULL;
345 
346       if (isidb) {
347         j = jj;
348         args[j++] = "-pid";
349         args[j++] = pid;
350         args[j++] = "-gdb";
351         args[j++] = program;
352         args[j++] = NULL;
353       }
354       if (islldb) {
355         j = jj;
356         args[j++] = "-p";
357         args[j++] = pid;
358         args[j++] = NULL;
359       }
360       if (isdbx) {
361         j = jj;
362 #if defined(PETSC_USE_P_FOR_DEBUGGER)
363         args[j++] = "-p";
364         args[j++] = pid;
365         args[j++] = program;
366 #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER)
367         args[j++] = "-l";
368         args[j++] = "ALL";
369         args[j++] = "-P";
370         args[j++] = pid;
371         args[j++] = program;
372 #elif defined(PETSC_USE_A_FOR_DEBUGGER)
373         args[j++] = "-a";
374         args[j++] = pid;
375 #elif defined(PETSC_USE_PID_FOR_DEBUGGER)
376         args[j++] = "-pid";
377         args[j++] = pid;
378         args[j++] = program;
379 #else
380         args[j++] = program;
381         args[j++] = pid;
382 #endif
383         args[j++] = NULL;
384       }
385       if (UseDebugTerminal) {
386         if (display[0]) printf("PETSC: Attaching %s to %s of pid %s on display %s on machine %s\n",PetscDebugger,program,pid,display,hostname);
387         else            printf("PETSC: Attaching %s to %s on pid %s on %s\n",PetscDebugger,program,pid,hostname);
388 
389         if (execvp(args[0],(char**)args)  < 0) {
390           perror("Unable to start debugger in xterm");
391           exit(0);
392         }
393       } else {
394         printf("PETSC: Attaching %s to %s of pid %s on %s\n",PetscDebugger,program,pid,hostname);
395         if (execvp(args[0],(char**)args)  < 0) {
396           perror("Unable to start debugger");
397           exit(0);
398         }
399       }
400     }
401   } else {   /* I am the child, continue with user code */
402     sleeptime = 10; /* default to sleep waiting for debugger */
403     PetscCall(PetscOptionsGetReal(NULL,NULL,"-debugger_pause",&sleeptime,NULL));
404     if (sleeptime < 0) sleeptime = -sleeptime;
405 #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP)
406     /*
407         HP cannot attach process to sleeping debugger, hence count instead
408     */
409     {
410       PetscReal x = 1.0;
411       int       i =10000000;
412       while (i--) x++;  /* cannot attach to sleeper */
413     }
414 #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY)
415     /*
416         IBM sleep may return at anytime, hence must see if there is more time to sleep
417     */
418     {
419       int left = sleeptime;
420       while (left > 0) left = PetscSleep(left) - 1;
421     }
422 #else
423     PetscSleep(sleeptime);
424 #endif
425   }
426 #endif
427   PetscFunctionReturn(0);
428 }
429 
430 /*@C
431    PetscAttachDebuggerErrorHandler - Error handler that attaches
432    a debugger to a running process when an error is detected.
433    This routine is useful for examining variables, etc.
434 
435    Not Collective
436 
437    Input Parameters:
438 +  comm - communicator over which error occurred
439 .  line - the line number of the error (indicated by __LINE__)
440 .  file - the file in which the error was detected (indicated by __FILE__)
441 .  message - an error text string, usually just printed to the screen
442 .  number - the generic error number
443 .  p - PETSC_ERROR_INITIAL if error just detected, otherwise PETSC_ERROR_REPEAT
444 -  ctx - error handler context
445 
446    Options Database Keys:
447 +  -on_error_attach_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] - Activates debugger attachment
448 -  -start_in_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] [-debugger_ranks m,n]
449 
450    Level: developer
451 
452    Notes:
453    By default the GNU debugger, gdb, is used.  Alternatives are cuda-gdb, lldb, dbx and
454    xxgdb,xldb (on IBM rs6000), xdb (on HP-UX).
455 
456    Most users need not directly employ this routine and the other error
457    handlers, but can instead use the simplified interface SETERR, which has
458    the calling sequence
459 $     SETERRQ(PETSC_COMM_SELF,number,p,message)
460 
461    Notes for experienced users:
462    Use PetscPushErrorHandler() to set the desired error handler.  The
463    currently available PETSc error handlers are
464 $    PetscTraceBackErrorHandler()
465 $    PetscAttachDebuggerErrorHandler()
466 $    PetscAbortErrorHandler()
467    or you may write your own.
468 
469    Developer Notes:
470      This routine calls abort instead of returning because if it returned then MPI_Abort() would get called which can generate an exception
471      causing the debugger to be attached again in a cycle.
472 
473 .seealso: `PetscSetDebuggerFromString()`, `PetscSetDebugger()`, `PetscSetDefaultDebugger()`, `PetscError()`, `PetscPushErrorHandler()`, `PetscPopErrorHandler()`, `PetscTraceBackErrorHandler()`,
474           `PetscAbortErrorHandler()`, `PetscMPIAbortErrorHandler()`, `PetscEmacsClientErrorHandler()`, `PetscReturnErrorHandler()`, `PetscSetDebugTermainal()`
475 @*/
476 PetscErrorCode  PetscAttachDebuggerErrorHandler(MPI_Comm comm,int line,const char *fun,const char *file,PetscErrorCode num,PetscErrorType p,const char *mess,void *ctx)
477 {
478   PetscFunctionBegin;
479   if (!mess) mess = " ";
480 
481   if (fun) (*PetscErrorPrintf)("%s() at %s:%d %s\n",fun,file,line,mess);
482   else  (*PetscErrorPrintf)("%s:%d %s\n",file,line,mess);
483 
484   PetscAttachDebugger();
485   abort(); /* call abort because don't want to kill other MPI processes that may successfully attach to debugger */
486   PetscFunctionReturn(0);
487 }
488 
489 /*@C
490    PetscStopForDebugger - Prints a message to the screen indicating how to
491          attach to the process with the debugger and then waits for the
492          debugger to attach.
493 
494    Not Collective
495 
496    Options Database:
497 .   -stop_for_debugger - will stop for you to attach the debugger when PetscInitialize() is called
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 PetscCall()?
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   PetscCall(PetscStrcmp(PetscDebugger,"xxgdb",&isxxgdb));
545   PetscCall(PetscStrcmp(PetscDebugger,"ddd",&isddd));
546   PetscCall(PetscStrcmp(PetscDebugger,"kdbg",&iskdbg));
547   PetscCall(PetscStrcmp(PetscDebugger,"ups",&isups));
548   PetscCall(PetscStrcmp(PetscDebugger,"xldb",&isxldb));
549   PetscCall(PetscStrcmp(PetscDebugger,"xdb",&isxdb));
550   PetscCall(PetscStrcmp(PetscDebugger,"dbx",&isdbx));
551   PetscCall(PetscStrcmp(PetscDebugger,"lldb",&islldb));
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