xref: /petsc/src/sys/error/adebug.c (revision ee12ae39415b2e672d944cdca066227dadbf8b14)
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    Options Database Keys:
208 -  -start_in_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] [-debugger_ranks m,n] -debug_terminal xterm or Terminal (for Apple)
209 .  -on_error_attach_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] - Activates debugger attachment
210 
211    Level: advanced
212 
213    Developer Notes:
214     Since this can be called by the error handler should it be calling SETERRQ() and CHKERRQ()?
215 
216 .seealso: PetscSetDebugger(), PetscSetDefaultDebugger(), PetscSetDebugTerminal(), PetscAttachDebuggerErrorHandler(), PetscStopForDebugger()
217 @*/
218 PetscErrorCode  PetscAttachDebugger(void)
219 {
220 #if !defined(PETSC_CANNOT_START_DEBUGGER) && defined(PETSC_HAVE_FORK)
221   int            child    =0;
222   PetscReal      sleeptime=0;
223   PetscErrorCode ierr;
224   char           program[PETSC_MAX_PATH_LEN],display[256],hostname[64];
225 #endif
226 
227   PetscFunctionBegin;
228 #if defined(PETSC_CANNOT_START_DEBUGGER) || !defined(PETSC_HAVE_FORK)
229   (*PetscErrorPrintf)("System cannot start debugger\n");
230   (*PetscErrorPrintf)("On Cray run program in Totalview debugger\n");
231   (*PetscErrorPrintf)("On Windows use Developer Studio(MSDEV)\n");
232   PETSCABORT(PETSC_COMM_WORLD,PETSC_ERR_SUP_SYS);
233 #else
234   ierr = PetscGetDisplay(display,sizeof(display));CHKERRQ(ierr);
235   ierr = PetscGetProgramName(program,sizeof(program));CHKERRQ(ierr);
236   if (ierr) {
237     (*PetscErrorPrintf)("Cannot determine program name\n");
238     PetscFunctionReturn(PETSC_ERR_SYS);
239   }
240   if (!program[0]) {
241     (*PetscErrorPrintf)("Cannot determine program name\n");
242     PetscFunctionReturn(PETSC_ERR_SYS);
243   }
244   child = (int)fork();
245   if (child < 0) {
246     (*PetscErrorPrintf)("Error in fork() prior to attaching debugger\n");
247     PetscFunctionReturn(PETSC_ERR_SYS);
248   }
249   petscindebugger = PETSC_TRUE;
250 
251   /*
252       Swap role the parent and child. This is (I think) so that control c typed
253     in the debugger goes to the correct process.
254   */
255 #if !defined(PETSC_DO_NOT_SWAP_CHILD_FOR_DEBUGGER)
256   if (child) child = 0;
257   else       child = (int)getppid();
258 #endif
259 
260   if (child) { /* I am the parent, will run the debugger */
261     const char *args[10];
262     char       pid[10];
263     PetscInt   j,jj;
264     PetscBool  isdbx,isidb,isxldb,isxxgdb,isups,isxdb,isworkshop,isddd,iskdbg,islldb;
265 
266     ierr = PetscGetHostName(hostname,sizeof(hostname));CHKERRQ(ierr);
267     /*
268          We need to send a continue signal to the "child" process on the
269        alpha, otherwise it just stays off forever
270     */
271 #if defined(PETSC_NEED_KILL_FOR_DEBUGGER)
272     kill(child,SIGCONT);
273 #endif
274     sprintf(pid,"%d",child);
275 
276     ierr = PetscStrcmp(PetscDebugger,"xxgdb",&isxxgdb);CHKERRQ(ierr);
277     ierr = PetscStrcmp(PetscDebugger,"ddd",&isddd);CHKERRQ(ierr);
278     ierr = PetscStrcmp(PetscDebugger,"kdbg",&iskdbg);CHKERRQ(ierr);
279     ierr = PetscStrcmp(PetscDebugger,"ups",&isups);CHKERRQ(ierr);
280     ierr = PetscStrcmp(PetscDebugger,"xldb",&isxldb);CHKERRQ(ierr);
281     ierr = PetscStrcmp(PetscDebugger,"xdb",&isxdb);CHKERRQ(ierr);
282     ierr = PetscStrcmp(PetscDebugger,"dbx",&isdbx);CHKERRQ(ierr);
283     ierr = PetscStrcmp(PetscDebugger,"idb",&isidb);CHKERRQ(ierr);
284     ierr = PetscStrcmp(PetscDebugger,"workshop",&isworkshop);CHKERRQ(ierr);
285     ierr = PetscStrcmp(PetscDebugger,"lldb",&islldb);CHKERRQ(ierr);
286 
287     if (isxxgdb || isups || isddd) {
288       args[1] = program; args[2] = pid; args[3] = "-display";
289       args[0] = PetscDebugger; args[4] = display; args[5] = NULL;
290       printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname);
291       if (execvp(args[0],(char**)args)  < 0) {
292         perror("Unable to start debugger");
293         exit(0);
294       }
295     } else if (iskdbg) {
296       args[1] = "-p"; args[2] = pid; args[3] = program;  args[4] = "-display";
297       args[0] = PetscDebugger; args[5] = display; args[6] = NULL;
298       printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[3],pid,hostname);
299       if (execvp(args[0],(char**)args)  < 0) {
300         perror("Unable to start debugger");
301         exit(0);
302       }
303     } else if (isxldb) {
304       args[1] = "-a"; args[2] = pid; args[3] = program;  args[4] = "-display";
305       args[0] = PetscDebugger; args[5] = display; args[6] = NULL;
306       printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname);
307       if (execvp(args[0],(char**)args)  < 0) {
308         perror("Unable to start debugger");
309         exit(0);
310       }
311     } else if (isworkshop) {
312       args[1] = "-s"; args[2] = pid; args[3] = "-D"; args[4] = "-";
313       args[0] = PetscDebugger; args[5] = pid; args[6] = "-display"; args[7] = display; args[8] = NULL;
314       printf("PETSC: Attaching %s to %s on %s\n",args[0],pid,hostname);
315       if (execvp(args[0],(char**)args)  < 0) {
316         perror("Unable to start debugger");
317         exit(0);
318       }
319     } else {
320       j = 0;
321       if (UseDebugTerminal) {
322         PetscBool cmp;
323         char      *tmp,*tmp1;
324         ierr = PetscStrncmp(DebugTerminal,"Terminal",8,&cmp);CHKERRQ(ierr);
325         if (cmp) {
326           char command[1024];
327           ierr = PetscSNPrintf(command,sizeof(command),"osascript -e 'tell app \"Terminal\" to do script \"lldb  -p %s  %s \"'\n",pid,program);CHKERRQ(ierr);
328           ierr = PetscPOpen(PETSC_COMM_SELF,NULL,command,"r",NULL);CHKERRQ(ierr);
329           exit(0);
330         }
331 
332         ierr = PetscStrncmp(DebugTerminal,"screen",6,&cmp);CHKERRQ(ierr);
333         if (!cmp) {ierr = PetscStrncmp(DebugTerminal,"gnome-terminal",6,&cmp);CHKERRQ(ierr);}
334         if (cmp) display[0] = 0; /* when using screen, we never pass -display */
335         args[j++] = tmp = DebugTerminal;
336         if (display[0]) {
337           args[j++] = "-display"; args[j++] = display;
338         }
339         while (*tmp) {
340           ierr = PetscStrchr(tmp,' ',&tmp1);CHKERRQ(ierr);
341           if (!tmp1) break;
342           *tmp1     = 0;
343           tmp       = tmp1+1;
344           args[j++] = tmp;
345         }
346       }
347       args[j++] = PetscDebugger;
348       jj = j;
349       /* this is for default gdb */
350       args[j++] = program;
351       args[j++] = pid;
352       args[j++] = NULL;
353 
354       if (isidb) {
355         j = jj;
356         args[j++] = "-pid";
357         args[j++] = pid;
358         args[j++] = "-gdb";
359         args[j++] = program;
360         args[j++] = NULL;
361       }
362       if (islldb) {
363         j = jj;
364         args[j++] = "-p";
365         args[j++] = pid;
366         args[j++] = NULL;
367       }
368       if (isdbx) {
369         j = jj;
370 #if defined(PETSC_USE_P_FOR_DEBUGGER)
371         args[j++] = "-p";
372         args[j++] = pid;
373         args[j++] = program;
374 #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER)
375         args[j++] = "-l";
376         args[j++] = "ALL";
377         args[j++] = "-P";
378         args[j++] = pid;
379         args[j++] = program;
380 #elif defined(PETSC_USE_A_FOR_DEBUGGER)
381         args[j++] = "-a";
382         args[j++] = pid;
383 #elif defined(PETSC_USE_PID_FOR_DEBUGGER)
384         args[j++] = "-pid";
385         args[j++] = pid;
386         args[j++] = program;
387 #else
388         args[j++] = program;
389         args[j++] = pid;
390 #endif
391         args[j++] = NULL;
392       }
393       if (UseDebugTerminal) {
394         if (display[0]) printf("PETSC: Attaching %s to %s of pid %s on display %s on machine %s\n",PetscDebugger,program,pid,display,hostname);
395         else            printf("PETSC: Attaching %s to %s on pid %s on %s\n",PetscDebugger,program,pid,hostname);
396 
397         if (execvp(args[0],(char**)args)  < 0) {
398           perror("Unable to start debugger in xterm");
399           exit(0);
400         }
401       } else {
402         printf("PETSC: Attaching %s to %s of pid %s on %s\n",PetscDebugger,program,pid,hostname);
403         if (execvp(args[0],(char**)args)  < 0) {
404           perror("Unable to start debugger");
405           exit(0);
406         }
407       }
408     }
409   } else {   /* I am the child, continue with user code */
410     sleeptime = 10; /* default to sleep waiting for debugger */
411     ierr = PetscOptionsGetReal(NULL,NULL,"-debugger_pause",&sleeptime,NULL);CHKERRQ(ierr);
412     if (sleeptime < 0) sleeptime = -sleeptime;
413 #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP)
414     /*
415         HP cannot attach process to sleeping debugger, hence count instead
416     */
417     {
418       PetscReal x = 1.0;
419       int       i =10000000;
420       while (i--) x++;  /* cannot attach to sleeper */
421     }
422 #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY)
423     /*
424         IBM sleep may return at anytime, hence must see if there is more time to sleep
425     */
426     {
427       int left = sleeptime;
428       while (left > 0) left = PetscSleep(left) - 1;
429     }
430 #else
431     PetscSleep(sleeptime);
432 #endif
433   }
434 #endif
435   PetscFunctionReturn(0);
436 }
437 
438 /*@C
439    PetscAttachDebuggerErrorHandler - Error handler that attaches
440    a debugger to a running process when an error is detected.
441    This routine is useful for examining variables, etc.
442 
443    Not Collective
444 
445    Input Parameters:
446 +  comm - communicator over which error occurred
447 .  line - the line number of the error (indicated by __LINE__)
448 .  file - the file in which the error was detected (indicated by __FILE__)
449 .  message - an error text string, usually just printed to the screen
450 .  number - the generic error number
451 .  p - PETSC_ERROR_INITIAL if error just detected, otherwise PETSC_ERROR_REPEAT
452 -  ctx - error handler context
453 
454    Options Database Keys:
455 +  -on_error_attach_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] - Activates debugger attachment
456 -  -start_in_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] [-debugger_ranks m,n]
457 
458    Level: developer
459 
460    Notes:
461    By default the GNU debugger, gdb, is used.  Alternatives are cuda-gdb, lldb, dbx and
462    xxgdb,xldb (on IBM rs6000), xdb (on HP-UX).
463 
464    Most users need not directly employ this routine and the other error
465    handlers, but can instead use the simplified interface SETERR, which has
466    the calling sequence
467 $     SETERRQ(PETSC_COMM_SELF,number,p,message)
468 
469    Notes for experienced users:
470    Use PetscPushErrorHandler() to set the desired error handler.  The
471    currently available PETSc error handlers are
472 $    PetscTraceBackErrorHandler()
473 $    PetscAttachDebuggerErrorHandler()
474 $    PetscAbortErrorHandler()
475    or you may write your own.
476 
477 
478 .seealso:  PetscSetDebuggerFromString(), PetscSetDebugger(), PetscSetDefaultDebugger(), PetscError(), PetscPushErrorHandler(), PetscPopErrorHandler(), PetscTraceBackErrorHandler(),
479            PetscAbortErrorHandler(), PetscMPIAbortErrorHandler(), PetscEmacsClientErrorHandler(), PetscReturnErrorHandler(), PetscSetDebugTermainal()
480 @*/
481 PetscErrorCode  PetscAttachDebuggerErrorHandler(MPI_Comm comm,int line,const char *fun,const char *file,PetscErrorCode num,PetscErrorType p,const char *mess,void *ctx)
482 {
483   PetscErrorCode ierr;
484 
485   PetscFunctionBegin;
486   if (!fun) fun = "User provided function";
487   if (!mess) mess = " ";
488 
489   (*PetscErrorPrintf)("%s() at %s:%d %s\n",fun,file,line,mess);
490 
491   ierr = PetscAttachDebugger();
492   if (ierr) abort(); /* call abort because don't want to kill other MPI processes that may successfully attach to debugger */
493   PetscFunctionReturn(0);
494 }
495 
496 /*@C
497    PetscStopForDebugger - Prints a message to the screen indicating how to
498          attach to the process with the debugger and then waits for the
499          debugger to attach.
500 
501    Not Collective
502 
503    Options Database:
504 .   -stop_for_debugger - will stop for you to attach the debugger when PetscInitialize() is called
505 
506    Level: developer
507 
508    Notes:
509     This is likely never needed since PetscAttachDebugger() is easier to use and seems to always work.
510 
511    Developer Notes:
512     Since this can be called by the error handler, should it be calling SETERRQ() and CHKERRQ()?
513 
514 .seealso: PetscSetDebugger(), PetscAttachDebugger()
515 @*/
516 PetscErrorCode  PetscStopForDebugger(void)
517 {
518   PetscErrorCode ierr;
519   PetscInt       sleeptime=0;
520 #if !defined(PETSC_CANNOT_START_DEBUGGER)
521   int            ppid;
522   PetscMPIInt    rank;
523   char           program[PETSC_MAX_PATH_LEN],hostname[256];
524   PetscBool      isdbx,isxldb,isxxgdb,isddd,iskdbg,isups,isxdb,islldb;
525 #endif
526 
527   PetscFunctionBegin;
528 #if defined(PETSC_CANNOT_START_DEBUGGER)
529   (*PetscErrorPrintf)("System cannot start debugger; just continuing program\n");
530 #else
531   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
532   if (ierr) rank = 0; /* ignore error since this may be already in error handler */
533   ierr = PetscGetHostName(hostname,sizeof(hostname));
534   if (ierr) {
535     (*PetscErrorPrintf)("Cannot determine hostname; just continuing program\n");
536     PetscFunctionReturn(0);
537   }
538 
539   ierr = PetscGetProgramName(program,sizeof(program));
540   if (ierr) {
541     (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n");
542     PetscFunctionReturn(0);
543   }
544   if (!program[0]) {
545     (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n");
546     PetscFunctionReturn(0);
547   }
548 
549   ppid = getpid();
550 
551   ierr = PetscStrcmp(PetscDebugger,"xxgdb",&isxxgdb);CHKERRQ(ierr);
552   ierr = PetscStrcmp(PetscDebugger,"ddd",&isddd);CHKERRQ(ierr);
553   ierr = PetscStrcmp(PetscDebugger,"kdbg",&iskdbg);CHKERRQ(ierr);
554   ierr = PetscStrcmp(PetscDebugger,"ups",&isups);CHKERRQ(ierr);
555   ierr = PetscStrcmp(PetscDebugger,"xldb",&isxldb);CHKERRQ(ierr);
556   ierr = PetscStrcmp(PetscDebugger,"xdb",&isxdb);CHKERRQ(ierr);
557   ierr = PetscStrcmp(PetscDebugger,"dbx",&isdbx);CHKERRQ(ierr);
558   ierr = PetscStrcmp(PetscDebugger,"lldb",&islldb);CHKERRQ(ierr);
559 
560   if (isxxgdb || isups || isddd || iskdbg) printf("[%d]%s>>%s %s %d\n",rank,hostname,PetscDebugger,program,ppid);
561   else if (isxldb) printf("[%d]%s>>%s -a %d %s\n",rank,hostname,PetscDebugger,ppid,program);
562   else if (islldb) printf("[%d]%s>>%s -p %d\n",rank,hostname,PetscDebugger,ppid);
563   else if (isdbx) {
564 #if defined(PETSC_USE_P_FOR_DEBUGGER)
565      printf("[%d]%s>>%s -p %d %s\n",rank,hostname,PetscDebugger,ppid,program);
566 #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER)
567      printf("[%d]%s>>%s -l ALL -P %d %s\n",rank,hostname,PetscDebugger,ppid,program);
568 #elif defined(PETSC_USE_A_FOR_DEBUGGER)
569      printf("[%d]%s>>%s -a %d\n",rank,hostname,PetscDebugger,ppid);
570 #elif defined(PETSC_USE_PID_FOR_DEBUGGER)
571      printf("[%d]%s>>%s -pid %d %s\n",rank,hostname,PetscDebugger,ppid,program);
572 #else
573      printf("[%d]%s>>%s %s %d\n",rank,hostname,PetscDebugger,program,ppid);
574 #endif
575   }
576 #endif /* PETSC_CANNOT_START_DEBUGGER */
577 
578   fflush(stdout); /* ignore error because may already be in error handler */
579 
580   sleeptime = 25; /* default to sleep waiting for debugger */
581   PetscOptionsGetInt(NULL,NULL,"-debugger_pause",&sleeptime,NULL); /* ignore error because may already be in error handler */
582   if (sleeptime < 0) sleeptime = -sleeptime;
583 #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP)
584   /*
585       HP cannot attach process to sleeping debugger, hence count instead
586   */
587   {
588     PetscReal x = 1.0;
589     int       i =10000000;
590     while (i--) x++;  /* cannot attach to sleeper */
591   }
592 #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY)
593   /*
594       IBM sleep may return at anytime, hence must see if there is more time to sleep
595   */
596   {
597     int left = sleeptime;
598     while (left > 0) left = sleep(left) - 1;
599   }
600 #else
601   PetscSleep(sleeptime);
602 #endif
603   PetscFunctionReturn(0);
604 }
605