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