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