xref: /petsc/src/sys/error/adebug.c (revision cc4c1da905d89950b196b027190941013bd3e15a)
1e5c89e4eSSatish Balay /*
2e5c89e4eSSatish Balay       Code to handle PETSc starting up in debuggers,etc.
3e5c89e4eSSatish Balay */
4cfbfffeaSBarry Smith #define PETSC_DESIRE_FEATURE_TEST_MACROS /* for fileno() */
5c6db04a5SJed Brown #include <petscsys.h>                    /*I   "petscsys.h"   I*/
6e5c89e4eSSatish Balay #include <signal.h>
7e5c89e4eSSatish Balay #if defined(PETSC_HAVE_UNISTD_H)
8e5c89e4eSSatish Balay   #include <unistd.h>
9e5c89e4eSSatish Balay #endif
10e5c89e4eSSatish Balay 
11e5c89e4eSSatish Balay /*
12e5c89e4eSSatish Balay       These are the debugger and display used if the debugger is started up
13e5c89e4eSSatish Balay */
14b59f628eSBarry Smith static char      PetscDebugger[PETSC_MAX_PATH_LEN];
155e96ac45SJed Brown static char      DebugTerminal[PETSC_MAX_PATH_LEN];
16c823fc1fSBarry Smith static PetscBool UseDebugTerminal    = PETSC_TRUE;
17baae8e41SSatish Balay PetscBool        petscwaitonerrorflg = PETSC_FALSE;
18bf4d2887SBarry Smith PetscBool        petscindebugger     = PETSC_FALSE;
19e5c89e4eSSatish Balay 
20*cc4c1da9SBarry Smith /*@
21c823fc1fSBarry Smith   PetscSetDebugTerminal - Sets the terminal to use for debugging.
225e96ac45SJed Brown 
23cf53795eSBarry Smith   Not Collective; No Fortran Support
245e96ac45SJed Brown 
25811af0c4SBarry Smith   Input Parameter:
26a2b725a8SWilliam Gropp . terminal - name of terminal and any flags required to execute a program.
27c3cd2bb4SBarry Smith               For example "xterm", "urxvt -e", "gnome-terminal -x".
286e25c4a1SBarry Smith               On Apple macOS you can use "Terminal" (note the capital T)
295e96ac45SJed Brown 
30811af0c4SBarry Smith   Options Database Key:
31c3cd2bb4SBarry Smith . -debug_terminal terminal - use this terminal instead of the default
325e96ac45SJed Brown 
335e96ac45SJed Brown   Level: developer
345e96ac45SJed Brown 
355e96ac45SJed Brown   Notes:
365e96ac45SJed Brown   You can start the debugger for all processes in the same GNU screen session.
376e25c4a1SBarry Smith .vb
386e25c4a1SBarry Smith   mpiexec -n 4 ./myapp -start_in_debugger -debug_terminal "screen -X -S debug screen"
396e25c4a1SBarry Smith .ve
405e96ac45SJed Brown 
415e96ac45SJed Brown   will open 4 windows in the session named "debug".
425e96ac45SJed Brown 
436e25c4a1SBarry Smith   The default terminal on Apple is Terminal, on other systems the default is xterm
44c823fc1fSBarry Smith 
45c3cd2bb4SBarry Smith .seealso: `PetscSetDebugger()`, `PetscAttachDebugger()`
465e96ac45SJed Brown @*/
47d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSetDebugTerminal(const char terminal[])
48d71ae5a4SJacob Faibussowitsch {
49c823fc1fSBarry Smith   PetscBool xterm;
505e96ac45SJed Brown 
515e96ac45SJed Brown   PetscFunctionBegin;
529566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(DebugTerminal, terminal, sizeof(DebugTerminal)));
539566063dSJacob Faibussowitsch   PetscCall(PetscStrcmp(terminal, "xterm", &xterm));
549566063dSJacob Faibussowitsch   if (xterm) PetscCall(PetscStrlcat(DebugTerminal, " -e", sizeof(DebugTerminal)));
553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
565e96ac45SJed Brown }
575e96ac45SJed Brown 
58*cc4c1da9SBarry Smith /*@
59e5c89e4eSSatish Balay   PetscSetDebugger - Sets options associated with the debugger.
60e5c89e4eSSatish Balay 
61cf53795eSBarry Smith   Not Collective; No Fortran Support
62e5c89e4eSSatish Balay 
63e5c89e4eSSatish Balay   Input Parameters:
64e5c89e4eSSatish Balay + debugger         - name of debugger, which should be in your path,
65c4fb7a8fSRichard Tran Mills                      usually "lldb", "dbx", "gdb", "cuda-gdb", "idb", "xxgdb", "kdgb" or "ddd". Also, HP-UX
66e5c89e4eSSatish Balay                      supports "xdb", and IBM rs6000 supports "xldb".
67e5c89e4eSSatish Balay 
686e25c4a1SBarry Smith - usedebugterminal - flag to indicate debugger window, set to either `PETSC_TRUE` (to indicate
696e25c4a1SBarry Smith                      debugger should be started in a new terminal window) or `PETSC_FALSE` (to start debugger
706e25c4a1SBarry Smith                      in initial window (the option `PETSC_FALSE` makes no sense when using more
718d359177SBarry Smith                      than one MPI process.)
72e5c89e4eSSatish Balay 
73e5c89e4eSSatish Balay   Level: developer
74e5c89e4eSSatish Balay 
75db781477SPatrick Sanan .seealso: `PetscAttachDebugger()`, `PetscAttachDebuggerErrorHandler()`, `PetscSetDebugTerminal()`
76e5c89e4eSSatish Balay @*/
77d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSetDebugger(const char debugger[], PetscBool usedebugterminal)
78d71ae5a4SJacob Faibussowitsch {
79e5c89e4eSSatish Balay   PetscFunctionBegin;
809566063dSJacob Faibussowitsch   if (debugger) PetscCall(PetscStrncpy(PetscDebugger, debugger, sizeof(PetscDebugger)));
81c823fc1fSBarry Smith   if (UseDebugTerminal) UseDebugTerminal = usedebugterminal;
823ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
83e5c89e4eSSatish Balay }
84e5c89e4eSSatish Balay 
858d359177SBarry Smith /*@C
86c823fc1fSBarry Smith   PetscSetDefaultDebugger - Causes PETSc to use its default debugger and output terminal
87e5c89e4eSSatish Balay 
88*cc4c1da9SBarry Smith   Not Collective, No Fortran Support
89e5c89e4eSSatish Balay 
908d359177SBarry Smith   Level: developer
91e5c89e4eSSatish Balay 
92c3cd2bb4SBarry Smith .seealso: `PetscSetDebugger()`, `PetscSetDebuggerFromString()`, `PetscAttachDebugger()`
93e5c89e4eSSatish Balay @*/
94d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscSetDefaultDebugger(void)
95d71ae5a4SJacob Faibussowitsch {
96e5c89e4eSSatish Balay   PetscFunctionBegin;
974211eb48SBarry Smith #if defined(PETSC_USE_DEBUGGER)
989566063dSJacob Faibussowitsch   PetscCall(PetscSetDebugger(PETSC_USE_DEBUGGER, PETSC_TRUE));
99e5c89e4eSSatish Balay #endif
100c823fc1fSBarry Smith #if defined(__APPLE__)
1019566063dSJacob Faibussowitsch   PetscCall(PetscSetDebugTerminal("Terminal"));
102c823fc1fSBarry Smith #else
1039566063dSJacob Faibussowitsch   PetscCall(PetscSetDebugTerminal("xterm"));
104c823fc1fSBarry Smith #endif
1053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
106e5c89e4eSSatish Balay }
107e5c89e4eSSatish Balay 
108d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscCheckDebugger_Private(const char defaultDbg[], const char string[], const char *debugger[])
109d71ae5a4SJacob Faibussowitsch {
110bbcf679cSJacob Faibussowitsch   char *f = NULL;
111e5c89e4eSSatish Balay 
112e5c89e4eSSatish Balay   PetscFunctionBegin;
1139566063dSJacob Faibussowitsch   PetscCall(PetscStrstr(string, defaultDbg, &f));
114e5c89e4eSSatish Balay   if (f) {
115bbcf679cSJacob Faibussowitsch     PetscBool exists;
116bbcf679cSJacob Faibussowitsch 
1179566063dSJacob Faibussowitsch     PetscCall(PetscTestFile(string, 'x', &exists));
118a297a907SKarl Rupp     if (exists) *debugger = string;
119a297a907SKarl Rupp     else *debugger = defaultDbg;
120e5c89e4eSSatish Balay   }
1213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
122e5c89e4eSSatish Balay }
123e5c89e4eSSatish Balay 
124*cc4c1da9SBarry Smith /*@
125e5c89e4eSSatish Balay   PetscSetDebuggerFromString - Set the complete path for the
126e5c89e4eSSatish Balay   debugger for PETSc to use.
127e5c89e4eSSatish Balay 
12820f4b53cSBarry Smith   Not Collective
129e5c89e4eSSatish Balay 
13010450e9eSJacob Faibussowitsch   Input Parameter:
13110450e9eSJacob Faibussowitsch . string - the name of the debugger, for example "gdb"
13210450e9eSJacob Faibussowitsch 
1337c764164SBarry Smith   Level: developer
134e5c89e4eSSatish Balay 
135c3cd2bb4SBarry Smith .seealso: `PetscSetDebugger()`, `PetscSetDefaultDebugger()`, `PetscAttachDebugger()`
136e5c89e4eSSatish Balay @*/
137*cc4c1da9SBarry Smith PetscErrorCode PetscSetDebuggerFromString(const char string[])
138d71ae5a4SJacob Faibussowitsch {
1390298fd71SBarry Smith   const char *debugger    = NULL;
140c823fc1fSBarry Smith   PetscBool   useterminal = PETSC_TRUE;
141bbcf679cSJacob Faibussowitsch   char       *f           = NULL;
142e5c89e4eSSatish Balay 
143e5c89e4eSSatish Balay   PetscFunctionBegin;
1449566063dSJacob Faibussowitsch   PetscCall(PetscStrstr(string, "noxterm", &f));
145c823fc1fSBarry Smith   if (f) useterminal = PETSC_FALSE;
1469566063dSJacob Faibussowitsch   PetscCall(PetscStrstr(string, "ddd", &f));
147c823fc1fSBarry Smith   if (f) useterminal = PETSC_FALSE;
1489566063dSJacob Faibussowitsch   PetscCall(PetscStrstr(string, "noterminal", &f));
149c823fc1fSBarry Smith   if (f) useterminal = PETSC_FALSE;
1509566063dSJacob Faibussowitsch   PetscCall(PetscCheckDebugger_Private("xdb", string, &debugger));
1519566063dSJacob Faibussowitsch   PetscCall(PetscCheckDebugger_Private("dbx", string, &debugger));
1529566063dSJacob Faibussowitsch   PetscCall(PetscCheckDebugger_Private("xldb", string, &debugger));
1539566063dSJacob Faibussowitsch   PetscCall(PetscCheckDebugger_Private("gdb", string, &debugger));
1549566063dSJacob Faibussowitsch   PetscCall(PetscCheckDebugger_Private("cuda-gdb", string, &debugger));
1559566063dSJacob Faibussowitsch   PetscCall(PetscCheckDebugger_Private("idb", string, &debugger));
1569566063dSJacob Faibussowitsch   PetscCall(PetscCheckDebugger_Private("xxgdb", string, &debugger));
1579566063dSJacob Faibussowitsch   PetscCall(PetscCheckDebugger_Private("ddd", string, &debugger));
1589566063dSJacob Faibussowitsch   PetscCall(PetscCheckDebugger_Private("kdbg", string, &debugger));
1599566063dSJacob Faibussowitsch   PetscCall(PetscCheckDebugger_Private("ups", string, &debugger));
1609566063dSJacob Faibussowitsch   PetscCall(PetscCheckDebugger_Private("workshop", string, &debugger));
1619566063dSJacob Faibussowitsch   PetscCall(PetscCheckDebugger_Private("pgdbg", string, &debugger));
1629566063dSJacob Faibussowitsch   PetscCall(PetscCheckDebugger_Private("pathdb", string, &debugger));
1639566063dSJacob Faibussowitsch   PetscCall(PetscCheckDebugger_Private("lldb", string, &debugger));
1649566063dSJacob Faibussowitsch   PetscCall(PetscSetDebugger(debugger, useterminal));
1653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
166e5c89e4eSSatish Balay }
167e5c89e4eSSatish Balay 
1682a2a2941SBarry Smith /*@
169811af0c4SBarry Smith   PetscWaitOnError - If an error is detected and the process would normally exit the main program with `MPI_Abort()` sleep instead
1702a2a2941SBarry Smith   of exiting.
1712a2a2941SBarry Smith 
1722a2a2941SBarry Smith   Not Collective
1732a2a2941SBarry Smith 
1742a2a2941SBarry Smith   Level: advanced
1752a2a2941SBarry Smith 
176811af0c4SBarry Smith   Note:
177c3cd2bb4SBarry Smith   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
1782a2a2941SBarry Smith   killing the user's debugging sessions.
1792a2a2941SBarry Smith 
180db781477SPatrick Sanan .seealso: `PetscSetDebugger()`, `PetscAttachDebugger()`
1812a2a2941SBarry Smith @*/
1823274405dSPierre Jolivet PetscErrorCode PetscWaitOnError(void)
183d71ae5a4SJacob Faibussowitsch {
184baae8e41SSatish Balay   petscwaitonerrorflg = PETSC_TRUE;
1853ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
1862a2a2941SBarry Smith }
187e5c89e4eSSatish Balay 
188e30d2299SSatish Balay /*@
189e5c89e4eSSatish Balay   PetscAttachDebugger - Attaches the debugger to the running process.
190e5c89e4eSSatish Balay 
191e5c89e4eSSatish Balay   Not Collective
192e5c89e4eSSatish Balay 
1931f690a00SBarry Smith   Options Database Keys:
1946e25c4a1SBarry Smith + -start_in_debugger [noxterm,lldb or gdb] [-display name] [-debugger_ranks m,n] - set debugger debug_terminal xterm or Terminal (for Apple)
1951f690a00SBarry Smith . -on_error_attach_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name]     - Activates debugger attachment
196c3cd2bb4SBarry Smith - -stop_for_debugger                                                             - print a message on how to attach the process with a debugger and then wait for the user to attach
1971f690a00SBarry Smith 
198e5c89e4eSSatish Balay   Level: advanced
199e5c89e4eSSatish Balay 
200c3cd2bb4SBarry Smith   Note:
201c3cd2bb4SBarry Smith   If you get the message " stdin is not a tty, hence unable to attach debugger, see PetscAttachDebugger()", this means the application
202c3cd2bb4SBarry Smith   is likely running in a batch system and you do not have terminal access to the process. You can try
203c3cd2bb4SBarry Smith   running with `-start_in_debugger` without the `noxterm` argument or `-stop_for_debugger`
204c3cd2bb4SBarry Smith 
2056e25c4a1SBarry Smith   Developer Note:
206c3cd2bb4SBarry Smith   Since this can be called by the error handler, should it be calling `SETERRQ()` and `PetscCall()`?
207f35f84d1SBarry Smith 
208db781477SPatrick Sanan .seealso: `PetscSetDebugger()`, `PetscSetDefaultDebugger()`, `PetscSetDebugTerminal()`, `PetscAttachDebuggerErrorHandler()`, `PetscStopForDebugger()`
209e5c89e4eSSatish Balay @*/
210d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscAttachDebugger(void)
211d71ae5a4SJacob Faibussowitsch {
2123ba16761SJacob Faibussowitsch   PetscErrorCode PETSC_UNUSED ierr;
213ed50d614Sprj- #if !defined(PETSC_CANNOT_START_DEBUGGER) && defined(PETSC_HAVE_FORK)
214e5c89e4eSSatish Balay   int       child     = 0;
215a6d0e24fSJed Brown   PetscReal sleeptime = 0;
216e5c89e4eSSatish Balay   char      program[PETSC_MAX_PATH_LEN], display[256], hostname[64];
217e5c89e4eSSatish Balay #endif
218e5c89e4eSSatish Balay 
219e5c89e4eSSatish Balay #if defined(PETSC_CANNOT_START_DEBUGGER) || !defined(PETSC_HAVE_FORK)
2203ba16761SJacob Faibussowitsch   ierr = (*PetscErrorPrintf)("System cannot start debugger\n");
2213ba16761SJacob Faibussowitsch   ierr = (*PetscErrorPrintf)("On Cray run program in Totalview debugger\n");
2223ba16761SJacob Faibussowitsch   ierr = (*PetscErrorPrintf)("On Windows use Developer Studio(MSDEV)\n");
22341e02c4dSJunchao Zhang   PETSCABORT(PETSC_COMM_WORLD, PETSC_ERR_SUP_SYS);
224e5c89e4eSSatish Balay #else
22563a3b9bcSJacob Faibussowitsch   if (PetscUnlikely(PetscGetDisplay(display, sizeof(display)))) {
226cfbfffeaSBarry Smith     ierr = (*PetscErrorPrintf)("PetscAttachDebugger: Cannot determine display\n");
22711cc89d2SBarry Smith     return PETSC_ERR_SYS;
2285f80ce2aSJacob Faibussowitsch   }
22963a3b9bcSJacob Faibussowitsch   if (PetscUnlikely(PetscGetProgramName(program, sizeof(program)))) {
230cfbfffeaSBarry Smith     ierr = (*PetscErrorPrintf)("PetscAttachDebugger: Cannot determine program name needed to attach debugger\n");
23111cc89d2SBarry Smith     return PETSC_ERR_SYS;
232e5c89e4eSSatish Balay   }
2335f80ce2aSJacob Faibussowitsch   if (PetscUnlikely(!program[0])) {
234cfbfffeaSBarry Smith     ierr = (*PetscErrorPrintf)("PetscAttachDebugger: Cannot determine program name needed to attach debugger\n");
235cfbfffeaSBarry Smith     return PETSC_ERR_SYS;
236cfbfffeaSBarry Smith   }
237ca85ed89SBarry Smith   if (PetscUnlikely(!isatty(fileno(stdin))) && !UseDebugTerminal) { printf("If the debugger exits immediately or hangs, this indicates you cannot use PetscAttachDebugger() in this situation\n\n"); }
238e5c89e4eSSatish Balay   child = (int)fork();
2395f80ce2aSJacob Faibussowitsch   if (PetscUnlikely(child < 0)) {
240cfbfffeaSBarry Smith     ierr = (*PetscErrorPrintf)("PetscAttachDebugger: Error in fork() prior to attaching debugger\n");
24111cc89d2SBarry Smith     return PETSC_ERR_SYS;
242e5c89e4eSSatish Balay   }
243bf4d2887SBarry Smith   petscindebugger = PETSC_TRUE;
244e5c89e4eSSatish Balay 
245e5c89e4eSSatish Balay   /*
246e5c89e4eSSatish Balay       Swap role the parent and child. This is (I think) so that control c typed
247e5c89e4eSSatish Balay     in the debugger goes to the correct process.
248e5c89e4eSSatish Balay   */
249234acd79SBarry Smith   #if !defined(PETSC_DO_NOT_SWAP_CHILD_FOR_DEBUGGER)
25063a3b9bcSJacob Faibussowitsch   child = child ? 0 : (int)getppid();
251234acd79SBarry Smith   #endif
252e5c89e4eSSatish Balay 
253e5c89e4eSSatish Balay   if (child) { /* I am the parent, will run the debugger */
254e5c89e4eSSatish Balay     const char *args[10];
255e5c89e4eSSatish Balay     char        pid[10];
2565e96ac45SJed Brown     PetscInt    j, jj;
2570e9bae81SBarry Smith     PetscBool   isdbx, isidb, isxldb, isxxgdb, isups, isxdb, isworkshop, isddd, iskdbg, islldb;
258e5c89e4eSSatish Balay 
2599566063dSJacob Faibussowitsch     PetscCall(PetscGetHostName(hostname, sizeof(hostname)));
260e5c89e4eSSatish Balay     /*
261e5c89e4eSSatish Balay          We need to send a continue signal to the "child" process on the
262e5c89e4eSSatish Balay        alpha, otherwise it just stays off forever
263e5c89e4eSSatish Balay     */
264e5c89e4eSSatish Balay   #if defined(PETSC_NEED_KILL_FOR_DEBUGGER)
265e5c89e4eSSatish Balay     kill(child, SIGCONT);
266e5c89e4eSSatish Balay   #endif
267a364092eSJacob Faibussowitsch     PetscCall(PetscSNPrintf(pid, PETSC_STATIC_ARRAY_LENGTH(pid), "%d", child));
268e5c89e4eSSatish Balay 
2699566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(PetscDebugger, "xxgdb", &isxxgdb));
2709566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(PetscDebugger, "ddd", &isddd));
2719566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(PetscDebugger, "kdbg", &iskdbg));
2729566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(PetscDebugger, "ups", &isups));
2739566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(PetscDebugger, "xldb", &isxldb));
2749566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(PetscDebugger, "xdb", &isxdb));
2759566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(PetscDebugger, "dbx", &isdbx));
2769566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(PetscDebugger, "idb", &isidb));
2779566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(PetscDebugger, "workshop", &isworkshop));
2789566063dSJacob Faibussowitsch     PetscCall(PetscStrcmp(PetscDebugger, "lldb", &islldb));
279e5c89e4eSSatish Balay 
280e5c89e4eSSatish Balay     if (isxxgdb || isups || isddd) {
2819371c9d4SSatish Balay       args[1] = program;
2829371c9d4SSatish Balay       args[2] = pid;
2839371c9d4SSatish Balay       args[3] = "-display";
2849371c9d4SSatish Balay       args[0] = PetscDebugger;
2859371c9d4SSatish Balay       args[4] = display;
2869371c9d4SSatish Balay       args[5] = NULL;
287c5888dd7SBarry Smith       printf("PETSC: Attaching %s to %s %s on %s\n", args[0], args[1], pid, hostname);
288e5c89e4eSSatish Balay       if (execvp(args[0], (char **)args) < 0) {
289e5c89e4eSSatish Balay         perror("Unable to start debugger");
290e5c89e4eSSatish Balay         exit(0);
291e5c89e4eSSatish Balay       }
292bf902449SSatish Balay     } else if (iskdbg) {
2939371c9d4SSatish Balay       args[1] = "-p";
2949371c9d4SSatish Balay       args[2] = pid;
2959371c9d4SSatish Balay       args[3] = program;
2969371c9d4SSatish Balay       args[4] = "-display";
2979371c9d4SSatish Balay       args[0] = PetscDebugger;
2989371c9d4SSatish Balay       args[5] = display;
2999371c9d4SSatish Balay       args[6] = NULL;
300c5888dd7SBarry Smith       printf("PETSC: Attaching %s to %s %s on %s\n", args[0], args[3], pid, hostname);
301bf902449SSatish Balay       if (execvp(args[0], (char **)args) < 0) {
302bf902449SSatish Balay         perror("Unable to start debugger");
303bf902449SSatish Balay         exit(0);
304bf902449SSatish Balay       }
305e5c89e4eSSatish Balay     } else if (isxldb) {
3069371c9d4SSatish Balay       args[1] = "-a";
3079371c9d4SSatish Balay       args[2] = pid;
3089371c9d4SSatish Balay       args[3] = program;
3099371c9d4SSatish Balay       args[4] = "-display";
3109371c9d4SSatish Balay       args[0] = PetscDebugger;
3119371c9d4SSatish Balay       args[5] = display;
3129371c9d4SSatish Balay       args[6] = NULL;
313c5888dd7SBarry Smith       printf("PETSC: Attaching %s to %s %s on %s\n", args[0], args[1], pid, hostname);
314e5c89e4eSSatish Balay       if (execvp(args[0], (char **)args) < 0) {
315e5c89e4eSSatish Balay         perror("Unable to start debugger");
316e5c89e4eSSatish Balay         exit(0);
317e5c89e4eSSatish Balay       }
318e5c89e4eSSatish Balay     } else if (isworkshop) {
3199371c9d4SSatish Balay       args[1] = "-s";
3209371c9d4SSatish Balay       args[2] = pid;
3219371c9d4SSatish Balay       args[3] = "-D";
3229371c9d4SSatish Balay       args[4] = "-";
3239371c9d4SSatish Balay       args[0] = PetscDebugger;
3249371c9d4SSatish Balay       args[5] = pid;
3259371c9d4SSatish Balay       args[6] = "-display";
3269371c9d4SSatish Balay       args[7] = display;
3279371c9d4SSatish Balay       args[8] = NULL;
328c5888dd7SBarry Smith       printf("PETSC: Attaching %s to %s on %s\n", args[0], pid, hostname);
329e5c89e4eSSatish Balay       if (execvp(args[0], (char **)args) < 0) {
330e5c89e4eSSatish Balay         perror("Unable to start debugger");
331e5c89e4eSSatish Balay         exit(0);
332e5c89e4eSSatish Balay       }
3335e96ac45SJed Brown     } else {
3345e96ac45SJed Brown       j = 0;
335c823fc1fSBarry Smith       if (UseDebugTerminal) {
336ace3abfcSBarry Smith         PetscBool cmp;
337bbcf679cSJacob Faibussowitsch         char     *tmp, *tmp1 = NULL;
3389566063dSJacob Faibussowitsch         PetscCall(PetscStrncmp(DebugTerminal, "Terminal", 8, &cmp));
339c823fc1fSBarry Smith         if (cmp) {
340c823fc1fSBarry Smith           char command[1024];
3419483a8a2SBarry Smith           if (islldb) PetscCall(PetscSNPrintf(command, sizeof(command), "osascript -e 'tell app \"Terminal\" to do script \"lldb  -p %s \"'\n", pid));
3429483a8a2SBarry Smith           else {
3439483a8a2SBarry Smith             char fullprogram[PETSC_MAX_PATH_LEN];
3449483a8a2SBarry Smith             PetscCall(PetscGetFullPath(program, fullprogram, sizeof(fullprogram)));
3459483a8a2SBarry Smith             PetscCall(PetscSNPrintf(command, sizeof(command), "osascript -e 'tell app \"Terminal\" to do script \"%s  %s %s \"'\n", PetscDebugger, fullprogram, pid));
3469483a8a2SBarry Smith           }
347accbd18bSBarry Smith   #if defined(PETSC_HAVE_POPEN)
3489566063dSJacob Faibussowitsch           PetscCall(PetscPOpen(PETSC_COMM_SELF, NULL, command, "r", NULL));
349accbd18bSBarry Smith   #else
350accbd18bSBarry Smith           printf("-debug_terminal Terminal is not available on this system since PETSC_HAVE_POPEN is not defined in this configuration\n");
351accbd18bSBarry Smith   #endif
352c823fc1fSBarry Smith           exit(0);
353c823fc1fSBarry Smith         }
354c823fc1fSBarry Smith 
3559566063dSJacob Faibussowitsch         PetscCall(PetscStrncmp(DebugTerminal, "screen", 6, &cmp));
3569566063dSJacob Faibussowitsch         if (!cmp) PetscCall(PetscStrncmp(DebugTerminal, "gnome-terminal", 6, &cmp));
3575e96ac45SJed Brown         if (cmp) display[0] = 0; /* when using screen, we never pass -display */
3585e96ac45SJed Brown         args[j++] = tmp = DebugTerminal;
3595e96ac45SJed Brown         if (display[0]) {
3609371c9d4SSatish Balay           args[j++] = "-display";
3619371c9d4SSatish Balay           args[j++] = display;
3625e96ac45SJed Brown         }
3635e96ac45SJed Brown         while (*tmp) {
3649566063dSJacob Faibussowitsch           PetscCall(PetscStrchr(tmp, ' ', &tmp1));
3655e96ac45SJed Brown           if (!tmp1) break;
3665e96ac45SJed Brown           *tmp1     = 0;
3675e96ac45SJed Brown           tmp       = tmp1 + 1;
3685e96ac45SJed Brown           args[j++] = tmp;
3695e96ac45SJed Brown         }
3705e96ac45SJed Brown       }
371b59f628eSBarry Smith       args[j++] = PetscDebugger;
3725e96ac45SJed Brown       jj        = j;
373bf4d2887SBarry Smith       /* this is for default gdb */
374bf4d2887SBarry Smith       args[j++] = program;
375bf4d2887SBarry Smith       args[j++] = pid;
376bf4d2887SBarry Smith       args[j++] = NULL;
3775e96ac45SJed Brown 
378e5c89e4eSSatish Balay       if (isidb) {
3795e96ac45SJed Brown         j         = jj;
3805e96ac45SJed Brown         args[j++] = "-pid";
3815e96ac45SJed Brown         args[j++] = pid;
3825e96ac45SJed Brown         args[j++] = "-gdb";
3835e96ac45SJed Brown         args[j++] = program;
38402c9f0b5SLisandro Dalcin         args[j++] = NULL;
385e5c89e4eSSatish Balay       }
3860e9bae81SBarry Smith       if (islldb) {
3870e9bae81SBarry Smith         j         = jj;
3880e9bae81SBarry Smith         args[j++] = "-p";
3890e9bae81SBarry Smith         args[j++] = pid;
39002c9f0b5SLisandro Dalcin         args[j++] = NULL;
3910e9bae81SBarry Smith       }
392e5c89e4eSSatish Balay       if (isdbx) {
3935e96ac45SJed Brown         j = jj;
3948d359177SBarry Smith   #if defined(PETSC_USE_P_FOR_DEBUGGER)
3955e96ac45SJed Brown         args[j++] = "-p";
3965e96ac45SJed Brown         args[j++] = pid;
3975e96ac45SJed Brown         args[j++] = program;
398e5c89e4eSSatish Balay   #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER)
3995e96ac45SJed Brown         args[j++] = "-l";
4005e96ac45SJed Brown         args[j++] = "ALL";
4015e96ac45SJed Brown         args[j++] = "-P";
4025e96ac45SJed Brown         args[j++] = pid;
4035e96ac45SJed Brown         args[j++] = program;
404e5c89e4eSSatish Balay   #elif defined(PETSC_USE_A_FOR_DEBUGGER)
4055e96ac45SJed Brown         args[j++] = "-a";
4065e96ac45SJed Brown         args[j++] = pid;
407e5c89e4eSSatish Balay   #elif defined(PETSC_USE_PID_FOR_DEBUGGER)
4085e96ac45SJed Brown         args[j++] = "-pid";
4095e96ac45SJed Brown         args[j++] = pid;
4105e96ac45SJed Brown         args[j++] = program;
411493de400SSatish Balay   #else
412493de400SSatish Balay         args[j++] = program;
413493de400SSatish Balay         args[j++] = pid;
4148d359177SBarry Smith   #endif
41502c9f0b5SLisandro Dalcin         args[j++] = NULL;
416e5c89e4eSSatish Balay       }
417c823fc1fSBarry Smith       if (UseDebugTerminal) {
418c5888dd7SBarry Smith         if (display[0]) printf("PETSC: Attaching %s to %s of pid %s on display %s on machine %s\n", PetscDebugger, program, pid, display, hostname);
419c5888dd7SBarry Smith         else printf("PETSC: Attaching %s to %s on pid %s on %s\n", PetscDebugger, program, pid, hostname);
420a297a907SKarl Rupp 
4215e96ac45SJed Brown         if (execvp(args[0], (char **)args) < 0) {
4225e96ac45SJed Brown           perror("Unable to start debugger in xterm");
4235e96ac45SJed Brown           exit(0);
4245e96ac45SJed Brown         }
4255e96ac45SJed Brown       } else {
426c5888dd7SBarry Smith         printf("PETSC: Attaching %s to %s of pid %s on %s\n", PetscDebugger, program, pid, hostname);
427e5c89e4eSSatish Balay         if (execvp(args[0], (char **)args) < 0) {
428e5c89e4eSSatish Balay           perror("Unable to start debugger");
429e5c89e4eSSatish Balay           exit(0);
430e5c89e4eSSatish Balay         }
431e5c89e4eSSatish Balay       }
432e5c89e4eSSatish Balay     }
433e5c89e4eSSatish Balay   } else {          /* I am the child, continue with user code */
434e5c89e4eSSatish Balay     sleeptime = 10; /* default to sleep waiting for debugger */
4359566063dSJacob Faibussowitsch     PetscCall(PetscOptionsGetReal(NULL, NULL, "-debugger_pause", &sleeptime, NULL));
436e5c89e4eSSatish Balay     if (sleeptime < 0) sleeptime = -sleeptime;
437e5c89e4eSSatish Balay   #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP)
438e5c89e4eSSatish Balay     /*
439e5c89e4eSSatish Balay         HP cannot attach process to sleeping debugger, hence count instead
440e5c89e4eSSatish Balay     */
441e5c89e4eSSatish Balay     {
442e5c89e4eSSatish Balay       PetscReal x = 1.0;
443e5c89e4eSSatish Balay       int       i = 10000000;
444e5c89e4eSSatish Balay       while (i--) x++; /* cannot attach to sleeper */
445e5c89e4eSSatish Balay     }
446e5c89e4eSSatish Balay   #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY)
447e5c89e4eSSatish Balay     /*
448e5c89e4eSSatish Balay         IBM sleep may return at anytime, hence must see if there is more time to sleep
449e5c89e4eSSatish Balay     */
450e5c89e4eSSatish Balay     {
451e5c89e4eSSatish Balay       int left = sleeptime;
452a297a907SKarl Rupp       while (left > 0) left = PetscSleep(left) - 1;
453e5c89e4eSSatish Balay     }
454e5c89e4eSSatish Balay   #else
4553ba16761SJacob Faibussowitsch     PetscCall(PetscSleep(sleeptime));
456e5c89e4eSSatish Balay   #endif
457e5c89e4eSSatish Balay   }
458e5c89e4eSSatish Balay #endif
4593ba16761SJacob Faibussowitsch   return PETSC_SUCCESS;
460e5c89e4eSSatish Balay }
461e5c89e4eSSatish Balay 
462e5c89e4eSSatish Balay /*@C
463e5c89e4eSSatish Balay   PetscAttachDebuggerErrorHandler - Error handler that attaches
464e5c89e4eSSatish Balay   a debugger to a running process when an error is detected.
465e5c89e4eSSatish Balay   This routine is useful for examining variables, etc.
466e5c89e4eSSatish Balay 
467*cc4c1da9SBarry Smith   Not Collective, No Fortran Support
468e5c89e4eSSatish Balay 
469e5c89e4eSSatish Balay   Input Parameters:
470e32f2f54SBarry Smith + comm - communicator over which error occurred
4716e25c4a1SBarry Smith . line - the line number of the error (usually indicated by `__LINE__` in the calling routine)
4726e25c4a1SBarry Smith . fun  - the function name of the calling routine
4736e25c4a1SBarry Smith . file - the file in which the error was detected (usually indicated by `__FILE__` in the calling routine)
47410450e9eSJacob Faibussowitsch . mess - an error text string, usually just printed to the screen
47510450e9eSJacob Faibussowitsch . num  - the generic error number
476811af0c4SBarry Smith . p    - `PETSC_ERROR_INITIAL` if error just detected, otherwise `PETSC_ERROR_REPEAT`
477e5c89e4eSSatish Balay - ctx  - error handler context
478e5c89e4eSSatish Balay 
479e5c89e4eSSatish Balay   Level: developer
480e5c89e4eSSatish Balay 
481e5c89e4eSSatish Balay   Notes:
4826e25c4a1SBarry Smith   By default the GNU debugger, gdb, is used except on macOS where lldb is used.  Alternatives are cuda-gdb, lldb, dbx and
483e5c89e4eSSatish Balay   xxgdb,xldb (on IBM rs6000), xdb (on HP-UX).
484e5c89e4eSSatish Balay 
485e5c89e4eSSatish Balay   Most users need not directly employ this routine and the other error
486e5c89e4eSSatish Balay   handlers, but can instead use the simplified interface SETERR, which has
487e5c89e4eSSatish Balay   the calling sequence
4886e25c4a1SBarry Smith .vb
4896e25c4a1SBarry Smith   SETERRQ(PETSC_COMM_SELF, number, p, message)
4906e25c4a1SBarry Smith .ve
491e5c89e4eSSatish Balay 
492811af0c4SBarry Smith   Use `PetscPushErrorHandler()` to set the desired error handler.  The
493e5c89e4eSSatish Balay   currently available PETSc error handlers are
49420f4b53cSBarry Smith .vb
49520f4b53cSBarry Smith     PetscTraceBackErrorHandler()
49620f4b53cSBarry Smith     PetscAttachDebuggerErrorHandler()
49720f4b53cSBarry Smith     PetscAbortErrorHandler()
49820f4b53cSBarry Smith .ve
499e5c89e4eSSatish Balay   or you may write your own.
500e5c89e4eSSatish Balay 
5016e25c4a1SBarry Smith   Developer Note:
502811af0c4SBarry Smith   This routine calls abort instead of returning because if it returned then `MPI_Abort()` would get called which can generate an exception
50369412655SBarry Smith   causing the debugger to be attached again in a cycle.
50469412655SBarry Smith 
505db781477SPatrick Sanan .seealso: `PetscSetDebuggerFromString()`, `PetscSetDebugger()`, `PetscSetDefaultDebugger()`, `PetscError()`, `PetscPushErrorHandler()`, `PetscPopErrorHandler()`, `PetscTraceBackErrorHandler()`,
506db781477SPatrick Sanan           `PetscAbortErrorHandler()`, `PetscMPIAbortErrorHandler()`, `PetscEmacsClientErrorHandler()`, `PetscReturnErrorHandler()`, `PetscSetDebugTermainal()`
507e5c89e4eSSatish Balay @*/
508d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscAttachDebuggerErrorHandler(MPI_Comm comm, int line, const char *fun, const char *file, PetscErrorCode num, PetscErrorType p, const char *mess, void *ctx)
509d71ae5a4SJacob Faibussowitsch {
5103ba16761SJacob Faibussowitsch   PetscErrorCode ierr;
51110450e9eSJacob Faibussowitsch 
51210450e9eSJacob Faibussowitsch   (void)comm;
51310450e9eSJacob Faibussowitsch   (void)num;
51410450e9eSJacob Faibussowitsch   (void)p;
51510450e9eSJacob Faibussowitsch   (void)ctx;
516e5c89e4eSSatish Balay   if (!mess) mess = " ";
517e5c89e4eSSatish Balay 
5183ba16761SJacob Faibussowitsch   if (fun) ierr = (*PetscErrorPrintf)("%s() at %s:%d %s\n", fun, file, line, mess);
5193ba16761SJacob Faibussowitsch   else ierr = (*PetscErrorPrintf)("%s:%d %s\n", file, line, mess);
520e5c89e4eSSatish Balay 
5213ba16761SJacob Faibussowitsch   ierr = PetscAttachDebugger();
5223ba16761SJacob Faibussowitsch   (void)ierr;
523811af0c4SBarry Smith   abort(); /* call abort because don't want to kill other MPI ranks that may successfully attach to debugger */
5243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
525e5c89e4eSSatish Balay }
526e5c89e4eSSatish Balay 
527e5c89e4eSSatish Balay /*@C
528e5c89e4eSSatish Balay   PetscStopForDebugger - Prints a message to the screen indicating how to
529e5c89e4eSSatish Balay   attach to the process with the debugger and then waits for the
530e5c89e4eSSatish Balay   debugger to attach.
531e5c89e4eSSatish Balay 
532*cc4c1da9SBarry Smith   Not Collective, No Fortran Support
533e5c89e4eSSatish Balay 
534811af0c4SBarry Smith   Options Database Key:
5356e25c4a1SBarry Smith . -stop_for_debugger - will stop for you to attach the debugger when `PetscInitialize()` is called
5361f690a00SBarry Smith 
5378d359177SBarry Smith   Level: developer
538e5c89e4eSSatish Balay 
539811af0c4SBarry Smith   Note:
540811af0c4SBarry Smith   This is likely never needed since `PetscAttachDebugger()` is easier to use and seems to always work.
5418d359177SBarry Smith 
5426e25c4a1SBarry Smith   Developer Note:
543811af0c4SBarry Smith   Since this can be called by the error handler, should it be calling `SETERRQ()` and `PetscCall()`?
544f35f84d1SBarry Smith 
545db781477SPatrick Sanan .seealso: `PetscSetDebugger()`, `PetscAttachDebugger()`
546e5c89e4eSSatish Balay @*/
547d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscStopForDebugger(void)
548d71ae5a4SJacob Faibussowitsch {
549e5c89e4eSSatish Balay   PetscErrorCode ierr;
550e5c89e4eSSatish Balay   PetscInt       sleeptime = 0;
551e5c89e4eSSatish Balay #if !defined(PETSC_CANNOT_START_DEBUGGER)
55251ec2c11SGlenn Hammond   int         ppid;
553e5c89e4eSSatish Balay   PetscMPIInt rank;
554e5c89e4eSSatish Balay   char        program[PETSC_MAX_PATH_LEN], hostname[256];
5558d359177SBarry Smith   PetscBool   isdbx, isxldb, isxxgdb, isddd, iskdbg, isups, isxdb, islldb;
556e5c89e4eSSatish Balay #endif
557e5c89e4eSSatish Balay 
558e5c89e4eSSatish Balay   PetscFunctionBegin;
559e5c89e4eSSatish Balay #if defined(PETSC_CANNOT_START_DEBUGGER)
5603ba16761SJacob Faibussowitsch   PetscCall((*PetscErrorPrintf)("System cannot start debugger; just continuing program\n"));
561e5c89e4eSSatish Balay #else
5623ba16761SJacob Faibussowitsch   if (MPI_Comm_rank(PETSC_COMM_WORLD, &rank)) rank = 0; /* ignore error since this may be already in error handler */
563589a23caSBarry Smith   ierr = PetscGetHostName(hostname, sizeof(hostname));
564e5c89e4eSSatish Balay   if (ierr) {
5653ba16761SJacob Faibussowitsch     PetscCall((*PetscErrorPrintf)("Cannot determine hostname; just continuing program\n"));
5663ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
567e5c89e4eSSatish Balay   }
568e5c89e4eSSatish Balay 
569589a23caSBarry Smith   ierr = PetscGetProgramName(program, sizeof(program));
570e5c89e4eSSatish Balay   if (ierr) {
5713ba16761SJacob Faibussowitsch     PetscCall((*PetscErrorPrintf)("Cannot determine program name; just continuing program\n"));
5723ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
573e5c89e4eSSatish Balay   }
574e5c89e4eSSatish Balay   if (!program[0]) {
5753ba16761SJacob Faibussowitsch     PetscCall((*PetscErrorPrintf)("Cannot determine program name; just continuing program\n"));
5763ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
577e5c89e4eSSatish Balay   }
578e5c89e4eSSatish Balay 
579e5c89e4eSSatish Balay   ppid = getpid();
580e5c89e4eSSatish Balay 
5819566063dSJacob Faibussowitsch   PetscCall(PetscStrcmp(PetscDebugger, "xxgdb", &isxxgdb));
5829566063dSJacob Faibussowitsch   PetscCall(PetscStrcmp(PetscDebugger, "ddd", &isddd));
5839566063dSJacob Faibussowitsch   PetscCall(PetscStrcmp(PetscDebugger, "kdbg", &iskdbg));
5849566063dSJacob Faibussowitsch   PetscCall(PetscStrcmp(PetscDebugger, "ups", &isups));
5859566063dSJacob Faibussowitsch   PetscCall(PetscStrcmp(PetscDebugger, "xldb", &isxldb));
5869566063dSJacob Faibussowitsch   PetscCall(PetscStrcmp(PetscDebugger, "xdb", &isxdb));
5879566063dSJacob Faibussowitsch   PetscCall(PetscStrcmp(PetscDebugger, "dbx", &isdbx));
5889566063dSJacob Faibussowitsch   PetscCall(PetscStrcmp(PetscDebugger, "lldb", &islldb));
589e5c89e4eSSatish Balay 
590c5888dd7SBarry Smith   if (isxxgdb || isups || isddd || iskdbg) printf("[%d]%s>>%s %s %d\n", rank, hostname, PetscDebugger, program, ppid);
591c5888dd7SBarry Smith   else if (isxldb) printf("[%d]%s>>%s -a %d %s\n", rank, hostname, PetscDebugger, ppid, program);
592c5888dd7SBarry Smith   else if (islldb) printf("[%d]%s>>%s -p %d\n", rank, hostname, PetscDebugger, ppid);
5938d359177SBarry Smith   else if (isdbx) {
594e5c89e4eSSatish Balay   #if defined(PETSC_USE_P_FOR_DEBUGGER)
595c5888dd7SBarry Smith     printf("[%d]%s>>%s -p %d %s\n", rank, hostname, PetscDebugger, ppid, program);
596e5c89e4eSSatish Balay   #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER)
597c5888dd7SBarry Smith     printf("[%d]%s>>%s -l ALL -P %d %s\n", rank, hostname, PetscDebugger, ppid, program);
598e5c89e4eSSatish Balay   #elif defined(PETSC_USE_A_FOR_DEBUGGER)
599c5888dd7SBarry Smith     printf("[%d]%s>>%s -a %d\n", rank, hostname, PetscDebugger, ppid);
600e5c89e4eSSatish Balay   #elif defined(PETSC_USE_PID_FOR_DEBUGGER)
601c5888dd7SBarry Smith     printf("[%d]%s>>%s -pid %d %s\n", rank, hostname, PetscDebugger, ppid, program);
602e5c89e4eSSatish Balay   #else
603c5888dd7SBarry Smith     printf("[%d]%s>>%s %s %d\n", rank, hostname, PetscDebugger, program, ppid);
604e5c89e4eSSatish Balay   #endif
6058d359177SBarry Smith   }
606e5c89e4eSSatish Balay #endif /* PETSC_CANNOT_START_DEBUGGER */
607e5c89e4eSSatish Balay 
608f35f84d1SBarry Smith   fflush(stdout); /* ignore error because may already be in error handler */
609e5c89e4eSSatish Balay 
610e5c89e4eSSatish Balay   sleeptime = 25;                                                                         /* default to sleep waiting for debugger */
6113ba16761SJacob Faibussowitsch   PetscCallContinue(PetscOptionsGetInt(NULL, NULL, "-debugger_pause", &sleeptime, NULL)); /* ignore error because may already be in error handler */
612e5c89e4eSSatish Balay   if (sleeptime < 0) sleeptime = -sleeptime;
613e5c89e4eSSatish Balay #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP)
614e5c89e4eSSatish Balay   /*
615e5c89e4eSSatish Balay       HP cannot attach process to sleeping debugger, hence count instead
616e5c89e4eSSatish Balay   */
617e5c89e4eSSatish Balay   {
6183ba16761SJacob Faibussowitsch     // this *will* get optimized away by any compiler known to man
619e5c89e4eSSatish Balay     PetscReal x = 1.0;
620e5c89e4eSSatish Balay     int       i = 10000000;
621e5c89e4eSSatish Balay     while (i--) x++; /* cannot attach to sleeper */
622e5c89e4eSSatish Balay   }
623e5c89e4eSSatish Balay #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY)
624e5c89e4eSSatish Balay   /*
625e5c89e4eSSatish Balay       IBM sleep may return at anytime, hence must see if there is more time to sleep
626e5c89e4eSSatish Balay   */
627e5c89e4eSSatish Balay   {
628e5c89e4eSSatish Balay     int left = sleeptime;
629a297a907SKarl Rupp     while (left > 0) left = sleep(left) - 1;
630e5c89e4eSSatish Balay   }
631e5c89e4eSSatish Balay #else
6323ba16761SJacob Faibussowitsch   PetscCall(PetscSleep(sleeptime));
633e5c89e4eSSatish Balay #endif
6343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
635e5c89e4eSSatish Balay }
636