xref: /petsc/src/sys/error/adebug.c (revision c823fc1f4e9a95d0fa9549bc75dfa3b1db6e9a8a)
1e5c89e4eSSatish Balay /*
2e5c89e4eSSatish Balay       Code to handle PETSc starting up in debuggers,etc.
3e5c89e4eSSatish Balay */
4e5c89e4eSSatish Balay 
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];
16*c823fc1fSBarry Smith static PetscBool UseDebugTerminal = PETSC_TRUE;
17baae8e41SSatish Balay PetscBool        petscwaitonerrorflg = PETSC_FALSE;
18bf4d2887SBarry Smith PetscBool        petscindebugger  = PETSC_FALSE;
19e5c89e4eSSatish Balay 
205e96ac45SJed Brown /*@C
21*c823fc1fSBarry Smith    PetscSetDebugTerminal - Sets the terminal to use for debugging.
225e96ac45SJed Brown 
235e96ac45SJed Brown    Not Collective
245e96ac45SJed Brown 
255e96ac45SJed Brown    Input Parameters:
26a2b725a8SWilliam Gropp .  terminal - name of terminal and any flags required to execute a program.
27*c823fc1fSBarry Smith               For example xterm, "urxvt -e", "gnome-terminal -x".
28*c823fc1fSBarry Smith               On Apple MacOS you can use Terminal (note the capital T)
295e96ac45SJed Brown 
305e96ac45SJed Brown    Options Database Keys:
31*c823fc1fSBarry 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.
375e96ac45SJed Brown 
38a6404fbfSBarry Smith      mpiexec -n 4 ./myapp -start_in_debugger -debug_terminal "screen -X -S debug screen"
395e96ac45SJed Brown 
405e96ac45SJed Brown    will open 4 windows in the session named "debug".
415e96ac45SJed Brown 
42*c823fc1fSBarry Smith    The default on Apple is Terminal, on other systems the default is xterm
43*c823fc1fSBarry Smith 
445e96ac45SJed Brown    Fortran Note:
455e96ac45SJed Brown    This routine is not supported in Fortran.
465e96ac45SJed Brown 
475e96ac45SJed Brown .seealso: PetscSetDebugger()
485e96ac45SJed Brown @*/
497087cfbeSBarry Smith PetscErrorCode  PetscSetDebugTerminal(const char terminal[])
505e96ac45SJed Brown {
515e96ac45SJed Brown   PetscErrorCode ierr;
52*c823fc1fSBarry Smith   PetscBool      xterm;
535e96ac45SJed Brown 
545e96ac45SJed Brown   PetscFunctionBegin;
55589a23caSBarry Smith   ierr = PetscStrncpy(DebugTerminal,terminal,sizeof(DebugTerminal));CHKERRQ(ierr);
56*c823fc1fSBarry Smith   ierr = PetscStrcmp(terminal,"xterm",&xterm);CHKERRQ(ierr);
57*c823fc1fSBarry Smith   if (xterm) {
58*c823fc1fSBarry Smith     ierr = PetscStrlcat(DebugTerminal," -e",sizeof(DebugTerminal));CHKERRQ(ierr);
59*c823fc1fSBarry Smith   }
605e96ac45SJed Brown   PetscFunctionReturn(0);
615e96ac45SJed Brown }
625e96ac45SJed Brown 
63e5c89e4eSSatish Balay /*@C
64e5c89e4eSSatish Balay    PetscSetDebugger - Sets options associated with the debugger.
65e5c89e4eSSatish Balay 
66e5c89e4eSSatish Balay    Not Collective
67e5c89e4eSSatish Balay 
68e5c89e4eSSatish Balay    Input Parameters:
69e5c89e4eSSatish Balay +  debugger - name of debugger, which should be in your path,
70c4fb7a8fSRichard Tran Mills               usually "lldb", "dbx", "gdb", "cuda-gdb", "idb", "xxgdb", "kdgb" or "ddd". Also, HP-UX
71e5c89e4eSSatish Balay               supports "xdb", and IBM rs6000 supports "xldb".
72e5c89e4eSSatish Balay 
73*c823fc1fSBarry Smith -  usedebugterminal - flag to indicate debugger window, set to either PETSC_TRUE (to indicate
74*c823fc1fSBarry Smith             debugger should be started in a new terminal window) or PETSC_FALSE (to start debugger
758d359177SBarry Smith             in initial window (the option PETSC_FALSE makes no sense when using more
768d359177SBarry Smith             than one MPI process.)
77e5c89e4eSSatish Balay 
78e5c89e4eSSatish Balay    Level: developer
79e5c89e4eSSatish Balay 
80e5c89e4eSSatish Balay    Fortran Note:
81e5c89e4eSSatish Balay    This routine is not supported in Fortran.
82e5c89e4eSSatish Balay 
83*c823fc1fSBarry Smith .seealso: PetscAttachDebugger(), PetscAttachDebuggerErrorHandler(), PetscSetDebugTerminal()
84e5c89e4eSSatish Balay @*/
85*c823fc1fSBarry Smith PetscErrorCode  PetscSetDebugger(const char debugger[],PetscBool usedebugterminal)
86e5c89e4eSSatish Balay {
87e5c89e4eSSatish Balay   PetscErrorCode ierr;
88e5c89e4eSSatish Balay 
89e5c89e4eSSatish Balay   PetscFunctionBegin;
90e5c89e4eSSatish Balay   if (debugger) {
91589a23caSBarry Smith     ierr = PetscStrncpy(PetscDebugger,debugger,sizeof(PetscDebugger));CHKERRQ(ierr);
92e5c89e4eSSatish Balay   }
93*c823fc1fSBarry Smith   if (UseDebugTerminal) UseDebugTerminal = usedebugterminal;
94e5c89e4eSSatish Balay   PetscFunctionReturn(0);
95e5c89e4eSSatish Balay }
96e5c89e4eSSatish Balay 
978d359177SBarry Smith /*@C
98*c823fc1fSBarry Smith     PetscSetDefaultDebugger - Causes PETSc to use its default debugger and output terminal
99e5c89e4eSSatish Balay 
100e5c89e4eSSatish Balay    Not collective
101e5c89e4eSSatish Balay 
1028d359177SBarry Smith     Level: developer
103e5c89e4eSSatish Balay 
104e5c89e4eSSatish Balay .seealso: PetscSetDebugger(), PetscSetDebuggerFromString()
105e5c89e4eSSatish Balay @*/
1067087cfbeSBarry Smith PetscErrorCode  PetscSetDefaultDebugger(void)
107e5c89e4eSSatish Balay {
108e5c89e4eSSatish Balay   PetscErrorCode ierr;
109e5c89e4eSSatish Balay 
110e5c89e4eSSatish Balay   PetscFunctionBegin;
1114211eb48SBarry Smith #if defined(PETSC_USE_DEBUGGER)
1124211eb48SBarry Smith   ierr = PetscSetDebugger(PETSC_USE_DEBUGGER,PETSC_TRUE);CHKERRQ(ierr);
113e5c89e4eSSatish Balay #endif
114*c823fc1fSBarry Smith #if defined(__APPLE__)
115*c823fc1fSBarry Smith   ierr = PetscSetDebugTerminal("Terminal");CHKERRQ(ierr);
116*c823fc1fSBarry Smith #else
117*c823fc1fSBarry Smith   ierr = PetscSetDebugTerminal("xterm");CHKERRQ(ierr);
118*c823fc1fSBarry Smith #endif
119e5c89e4eSSatish Balay   PetscFunctionReturn(0);
120e5c89e4eSSatish Balay }
121e5c89e4eSSatish Balay 
122e5c89e4eSSatish Balay static PetscErrorCode PetscCheckDebugger_Private(const char defaultDbg[], const char string[], const char *debugger[])
123e5c89e4eSSatish Balay {
124ace3abfcSBarry Smith   PetscBool      exists;
125e5c89e4eSSatish Balay   char           *f;
126e5c89e4eSSatish Balay   PetscErrorCode ierr;
127e5c89e4eSSatish Balay 
128e5c89e4eSSatish Balay   PetscFunctionBegin;
129e5c89e4eSSatish Balay   ierr = PetscStrstr(string, defaultDbg, &f);CHKERRQ(ierr);
130e5c89e4eSSatish Balay   if (f) {
131e5c89e4eSSatish Balay     ierr = PetscTestFile(string, 'x', &exists);CHKERRQ(ierr);
132a297a907SKarl Rupp     if (exists) *debugger = string;
133a297a907SKarl Rupp     else        *debugger = defaultDbg;
134e5c89e4eSSatish Balay   }
135e5c89e4eSSatish Balay   PetscFunctionReturn(0);
136e5c89e4eSSatish Balay }
137e5c89e4eSSatish Balay 
138e5c89e4eSSatish Balay /*@C
139e5c89e4eSSatish Balay     PetscSetDebuggerFromString - Set the complete path for the
140e5c89e4eSSatish Balay        debugger for PETSc to use.
141e5c89e4eSSatish Balay 
142e5c89e4eSSatish Balay    Not collective
143e5c89e4eSSatish Balay 
1447c764164SBarry Smith    Level: developer
145e5c89e4eSSatish Balay 
146e5c89e4eSSatish Balay .seealso: PetscSetDebugger(), PetscSetDefaultDebugger()
147e5c89e4eSSatish Balay @*/
1487c764164SBarry Smith PetscErrorCode  PetscSetDebuggerFromString(const char *string)
149e5c89e4eSSatish Balay {
1500298fd71SBarry Smith   const char     *debugger = NULL;
151*c823fc1fSBarry Smith   PetscBool      useterminal     = PETSC_TRUE;
152e5c89e4eSSatish Balay   char           *f;
153e5c89e4eSSatish Balay   PetscErrorCode ierr;
154e5c89e4eSSatish Balay 
155e5c89e4eSSatish Balay   PetscFunctionBegin;
156e5c89e4eSSatish Balay   ierr = PetscStrstr(string, "noxterm", &f);CHKERRQ(ierr);
157*c823fc1fSBarry Smith   if (f) useterminal = PETSC_FALSE;
158e5c89e4eSSatish Balay   ierr = PetscStrstr(string, "ddd", &f);CHKERRQ(ierr);
159*c823fc1fSBarry Smith   if (f) useterminal = PETSC_FALSE;
160*c823fc1fSBarry Smith   ierr = PetscStrstr(string, "noterminal", &f);CHKERRQ(ierr);
161*c823fc1fSBarry Smith   if (f) useterminal = PETSC_FALSE;
162e5c89e4eSSatish Balay   ierr = PetscCheckDebugger_Private("xdb",      string, &debugger);CHKERRQ(ierr);
163e5c89e4eSSatish Balay   ierr = PetscCheckDebugger_Private("dbx",      string, &debugger);CHKERRQ(ierr);
164e5c89e4eSSatish Balay   ierr = PetscCheckDebugger_Private("xldb",     string, &debugger);CHKERRQ(ierr);
165e5c89e4eSSatish Balay   ierr = PetscCheckDebugger_Private("gdb",      string, &debugger);CHKERRQ(ierr);
166c4fb7a8fSRichard Tran Mills   ierr = PetscCheckDebugger_Private("cuda-gdb", string, &debugger);CHKERRQ(ierr);
167e5c89e4eSSatish Balay   ierr = PetscCheckDebugger_Private("idb",      string, &debugger);CHKERRQ(ierr);
168e5c89e4eSSatish Balay   ierr = PetscCheckDebugger_Private("xxgdb",    string, &debugger);CHKERRQ(ierr);
169e5c89e4eSSatish Balay   ierr = PetscCheckDebugger_Private("ddd",      string, &debugger);CHKERRQ(ierr);
170bf902449SSatish Balay   ierr = PetscCheckDebugger_Private("kdbg",     string, &debugger);CHKERRQ(ierr);
171e5c89e4eSSatish Balay   ierr = PetscCheckDebugger_Private("ups",      string, &debugger);CHKERRQ(ierr);
172e5c89e4eSSatish Balay   ierr = PetscCheckDebugger_Private("workshop", string, &debugger);CHKERRQ(ierr);
173e5c89e4eSSatish Balay   ierr = PetscCheckDebugger_Private("pgdbg",    string, &debugger);CHKERRQ(ierr);
174ecbcaa78SBarry Smith   ierr = PetscCheckDebugger_Private("pathdb",   string, &debugger);CHKERRQ(ierr);
1750e9bae81SBarry Smith   ierr = PetscCheckDebugger_Private("lldb",     string, &debugger);CHKERRQ(ierr);
176e5c89e4eSSatish Balay 
177*c823fc1fSBarry Smith   ierr = PetscSetDebugger(debugger, useterminal);CHKERRQ(ierr);
178e5c89e4eSSatish Balay   PetscFunctionReturn(0);
179e5c89e4eSSatish Balay }
180e5c89e4eSSatish Balay 
1812a2a2941SBarry Smith /*@
1822a2a2941SBarry Smith    PetscWaitOnError - If an error is detected and the process would normally exit the main program with MPI_Abort() sleep instead
1832a2a2941SBarry Smith                       of exiting.
1842a2a2941SBarry Smith 
1852a2a2941SBarry Smith    Not Collective
1862a2a2941SBarry Smith 
1872a2a2941SBarry Smith    Level: advanced
1882a2a2941SBarry Smith 
1892a2a2941SBarry Smith    Notes:
1902a2a2941SBarry 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
1912a2a2941SBarry Smith       killing the user's debugging sessions.
1922a2a2941SBarry Smith 
1932a2a2941SBarry Smith 
1942a2a2941SBarry Smith .seealso: PetscSetDebugger(), PetscAttachDebugger()
1952a2a2941SBarry Smith @*/
1962a2a2941SBarry Smith PetscErrorCode  PetscWaitOnError()
1972a2a2941SBarry Smith {
198baae8e41SSatish Balay   petscwaitonerrorflg  = PETSC_TRUE;
1992a2a2941SBarry Smith   return 0;
2002a2a2941SBarry Smith }
201e5c89e4eSSatish Balay 
202e30d2299SSatish Balay /*@
203e5c89e4eSSatish Balay    PetscAttachDebugger - Attaches the debugger to the running process.
204e5c89e4eSSatish Balay 
205e5c89e4eSSatish Balay    Not Collective
206e5c89e4eSSatish Balay 
207e5c89e4eSSatish Balay    Level: advanced
208e5c89e4eSSatish Balay 
20995452b02SPatrick Sanan    Developer Notes:
21095452b02SPatrick Sanan     Since this can be called by the error handler should it be calling SETERRQ() and CHKERRQ()?
211f35f84d1SBarry Smith 
212*c823fc1fSBarry Smith .seealso: PetscSetDebugger(), PetscSetDefaultDebugger(), PetscSetDebugTerminal()
213e5c89e4eSSatish Balay @*/
2147087cfbeSBarry Smith PetscErrorCode  PetscAttachDebugger(void)
215e5c89e4eSSatish Balay {
216ed50d614Sprj- #if !defined(PETSC_CANNOT_START_DEBUGGER) && defined(PETSC_HAVE_FORK)
217e5c89e4eSSatish Balay   int            child    =0;
218a6d0e24fSJed Brown   PetscReal      sleeptime=0;
219e5c89e4eSSatish Balay   PetscErrorCode ierr;
220e5c89e4eSSatish Balay   char           program[PETSC_MAX_PATH_LEN],display[256],hostname[64];
221e5c89e4eSSatish Balay #endif
222e5c89e4eSSatish Balay 
223e5c89e4eSSatish Balay   PetscFunctionBegin;
224e5c89e4eSSatish Balay #if defined(PETSC_CANNOT_START_DEBUGGER) || !defined(PETSC_HAVE_FORK)
225e5c89e4eSSatish Balay   (*PetscErrorPrintf)("System cannot start debugger\n");
226e5c89e4eSSatish Balay   (*PetscErrorPrintf)("On Cray run program in Totalview debugger\n");
227e5c89e4eSSatish Balay   (*PetscErrorPrintf)("On Windows use Developer Studio(MSDEV)\n");
22841e02c4dSJunchao Zhang   PETSCABORT(PETSC_COMM_WORLD,PETSC_ERR_SUP_SYS);
229e5c89e4eSSatish Balay #else
230589a23caSBarry Smith   ierr = PetscGetDisplay(display,sizeof(display));CHKERRQ(ierr);
231589a23caSBarry Smith   ierr = PetscGetProgramName(program,sizeof(program));CHKERRQ(ierr);
232e5c89e4eSSatish Balay   if (ierr) {
233e5c89e4eSSatish Balay     (*PetscErrorPrintf)("Cannot determine program name\n");
234e5c89e4eSSatish Balay     PetscFunctionReturn(1);
235e5c89e4eSSatish Balay   }
236e5c89e4eSSatish Balay   if (!program[0]) {
237e5c89e4eSSatish Balay     (*PetscErrorPrintf)("Cannot determine program name\n");
238e5c89e4eSSatish Balay     PetscFunctionReturn(1);
239e5c89e4eSSatish Balay   }
240e5c89e4eSSatish Balay   child = (int)fork();
241e5c89e4eSSatish Balay   if (child < 0) {
242e5c89e4eSSatish Balay     (*PetscErrorPrintf)("Error in fork() attaching debugger\n");
243e5c89e4eSSatish Balay     PetscFunctionReturn(1);
244e5c89e4eSSatish Balay   }
245bf4d2887SBarry Smith   petscindebugger = PETSC_TRUE;
246e5c89e4eSSatish Balay 
247e5c89e4eSSatish Balay   /*
248e5c89e4eSSatish Balay       Swap role the parent and child. This is (I think) so that control c typed
249e5c89e4eSSatish Balay     in the debugger goes to the correct process.
250e5c89e4eSSatish Balay   */
251234acd79SBarry Smith #if !defined(PETSC_DO_NOT_SWAP_CHILD_FOR_DEBUGGER)
252a297a907SKarl Rupp   if (child) child = 0;
253a297a907SKarl Rupp   else       child = (int)getppid();
254234acd79SBarry Smith #endif
255e5c89e4eSSatish Balay 
256e5c89e4eSSatish Balay   if (child) { /* I am the parent, will run the debugger */
257e5c89e4eSSatish Balay     const char *args[10];
258e5c89e4eSSatish Balay     char       pid[10];
2595e96ac45SJed Brown     PetscInt   j,jj;
2600e9bae81SBarry Smith     PetscBool  isdbx,isidb,isxldb,isxxgdb,isups,isxdb,isworkshop,isddd,iskdbg,islldb;
261e5c89e4eSSatish Balay 
262589a23caSBarry Smith     ierr = PetscGetHostName(hostname,sizeof(hostname));CHKERRQ(ierr);
263e5c89e4eSSatish Balay     /*
264e5c89e4eSSatish Balay          We need to send a continue signal to the "child" process on the
265e5c89e4eSSatish Balay        alpha, otherwise it just stays off forever
266e5c89e4eSSatish Balay     */
267e5c89e4eSSatish Balay #if defined(PETSC_NEED_KILL_FOR_DEBUGGER)
268e5c89e4eSSatish Balay     kill(child,SIGCONT);
269e5c89e4eSSatish Balay #endif
270e5c89e4eSSatish Balay     sprintf(pid,"%d",child);
271e5c89e4eSSatish Balay 
272b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"xxgdb",&isxxgdb);CHKERRQ(ierr);
273b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"ddd",&isddd);CHKERRQ(ierr);
274b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"kdbg",&iskdbg);CHKERRQ(ierr);
275b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"ups",&isups);CHKERRQ(ierr);
276b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"xldb",&isxldb);CHKERRQ(ierr);
277b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"xdb",&isxdb);CHKERRQ(ierr);
278b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"dbx",&isdbx);CHKERRQ(ierr);
279b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"idb",&isidb);CHKERRQ(ierr);
280b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"workshop",&isworkshop);CHKERRQ(ierr);
281b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"lldb",&islldb);CHKERRQ(ierr);
282e5c89e4eSSatish Balay 
283e5c89e4eSSatish Balay     if (isxxgdb || isups || isddd) {
284e5c89e4eSSatish Balay       args[1] = program; args[2] = pid; args[3] = "-display";
28502c9f0b5SLisandro Dalcin       args[0] = PetscDebugger; args[4] = display; args[5] = NULL;
286c5888dd7SBarry Smith       printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname);
287e5c89e4eSSatish Balay       if (execvp(args[0],(char**)args)  < 0) {
288e5c89e4eSSatish Balay         perror("Unable to start debugger");
289e5c89e4eSSatish Balay         exit(0);
290e5c89e4eSSatish Balay       }
291bf902449SSatish Balay     } else if (iskdbg) {
292bf902449SSatish Balay       args[1] = "-p"; args[2] = pid; args[3] = program;  args[4] = "-display";
29302c9f0b5SLisandro Dalcin       args[0] = PetscDebugger; args[5] = display; args[6] = NULL;
294c5888dd7SBarry Smith       printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[3],pid,hostname);
295bf902449SSatish Balay       if (execvp(args[0],(char**)args)  < 0) {
296bf902449SSatish Balay         perror("Unable to start debugger");
297bf902449SSatish Balay         exit(0);
298bf902449SSatish Balay       }
299e5c89e4eSSatish Balay     } else if (isxldb) {
300e5c89e4eSSatish Balay       args[1] = "-a"; args[2] = pid; args[3] = program;  args[4] = "-display";
30102c9f0b5SLisandro Dalcin       args[0] = PetscDebugger; args[5] = display; args[6] = NULL;
302c5888dd7SBarry Smith       printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname);
303e5c89e4eSSatish Balay       if (execvp(args[0],(char**)args)  < 0) {
304e5c89e4eSSatish Balay         perror("Unable to start debugger");
305e5c89e4eSSatish Balay         exit(0);
306e5c89e4eSSatish Balay       }
307e5c89e4eSSatish Balay     } else if (isworkshop) {
308e5c89e4eSSatish Balay       args[1] = "-s"; args[2] = pid; args[3] = "-D"; args[4] = "-";
30902c9f0b5SLisandro Dalcin       args[0] = PetscDebugger; args[5] = pid; args[6] = "-display"; args[7] = display; args[8] = NULL;
310c5888dd7SBarry Smith       printf("PETSC: Attaching %s to %s on %s\n",args[0],pid,hostname);
311e5c89e4eSSatish Balay       if (execvp(args[0],(char**)args)  < 0) {
312e5c89e4eSSatish Balay         perror("Unable to start debugger");
313e5c89e4eSSatish Balay         exit(0);
314e5c89e4eSSatish Balay       }
3155e96ac45SJed Brown     } else {
3165e96ac45SJed Brown       j = 0;
317*c823fc1fSBarry Smith       if (UseDebugTerminal) {
318ace3abfcSBarry Smith         PetscBool cmp;
3195e96ac45SJed Brown         char      *tmp,*tmp1;
320*c823fc1fSBarry Smith         ierr = PetscStrncmp(DebugTerminal,"Terminal",8,&cmp);CHKERRQ(ierr);
321*c823fc1fSBarry Smith         if (cmp) {
322*c823fc1fSBarry Smith           char command[1024];
323*c823fc1fSBarry Smith           ierr = PetscSNPrintf(command,sizeof(command),"osascript -e 'tell app \"Terminal\" to do script \"lldb  -p %s  %s \"'\n",pid,program);CHKERRQ(ierr);
324*c823fc1fSBarry Smith           ierr = PetscPOpen(PETSC_COMM_SELF,NULL,command,"r",NULL);CHKERRQ(ierr);
325*c823fc1fSBarry Smith           exit(0);
326*c823fc1fSBarry Smith         }
327*c823fc1fSBarry Smith 
3285e96ac45SJed Brown         ierr = PetscStrncmp(DebugTerminal,"screen",6,&cmp);CHKERRQ(ierr);
329a5ba6984SMatthew G. Knepley         if (!cmp) {ierr = PetscStrncmp(DebugTerminal,"gnome-terminal",6,&cmp);CHKERRQ(ierr);}
3305e96ac45SJed Brown         if (cmp) display[0] = 0; /* when using screen, we never pass -display */
3315e96ac45SJed Brown         args[j++] = tmp = DebugTerminal;
3325e96ac45SJed Brown         if (display[0]) {
3335e96ac45SJed Brown           args[j++] = "-display"; args[j++] = display;
3345e96ac45SJed Brown         }
3355e96ac45SJed Brown         while (*tmp) {
3365e96ac45SJed Brown           ierr = PetscStrchr(tmp,' ',&tmp1);CHKERRQ(ierr);
3375e96ac45SJed Brown           if (!tmp1) break;
3385e96ac45SJed Brown           *tmp1     = 0;
3395e96ac45SJed Brown           tmp       = tmp1+1;
3405e96ac45SJed Brown           args[j++] = tmp;
3415e96ac45SJed Brown         }
3425e96ac45SJed Brown       }
343b59f628eSBarry Smith       args[j++] = PetscDebugger;
3445e96ac45SJed Brown       jj = j;
345bf4d2887SBarry Smith       /* this is for default gdb */
346bf4d2887SBarry Smith       args[j++] = program;
347bf4d2887SBarry Smith       args[j++] = pid;
348bf4d2887SBarry Smith       args[j++] = NULL;
3495e96ac45SJed Brown 
350e5c89e4eSSatish Balay       if (isidb) {
3515e96ac45SJed Brown         j = jj;
3525e96ac45SJed Brown         args[j++] = "-pid";
3535e96ac45SJed Brown         args[j++] = pid;
3545e96ac45SJed Brown         args[j++] = "-gdb";
3555e96ac45SJed Brown         args[j++] = program;
35602c9f0b5SLisandro Dalcin         args[j++] = NULL;
357e5c89e4eSSatish Balay       }
3580e9bae81SBarry Smith       if (islldb) {
3590e9bae81SBarry Smith         j = jj;
3600e9bae81SBarry Smith         args[j++] = "-p";
3610e9bae81SBarry Smith         args[j++] = pid;
36202c9f0b5SLisandro Dalcin         args[j++] = NULL;
3630e9bae81SBarry Smith       }
364e5c89e4eSSatish Balay       if (isdbx) {
3655e96ac45SJed Brown         j = jj;
3668d359177SBarry Smith #if defined(PETSC_USE_P_FOR_DEBUGGER)
3675e96ac45SJed Brown         args[j++] = "-p";
3685e96ac45SJed Brown         args[j++] = pid;
3695e96ac45SJed Brown         args[j++] = program;
370e5c89e4eSSatish Balay #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER)
3715e96ac45SJed Brown         args[j++] = "-l";
3725e96ac45SJed Brown         args[j++] = "ALL";
3735e96ac45SJed Brown         args[j++] = "-P";
3745e96ac45SJed Brown         args[j++] = pid;
3755e96ac45SJed Brown         args[j++] = program;
376e5c89e4eSSatish Balay #elif defined(PETSC_USE_A_FOR_DEBUGGER)
3775e96ac45SJed Brown         args[j++] = "-a";
3785e96ac45SJed Brown         args[j++] = pid;
379e5c89e4eSSatish Balay #elif defined(PETSC_USE_PID_FOR_DEBUGGER)
3805e96ac45SJed Brown         args[j++] = "-pid";
3815e96ac45SJed Brown         args[j++] = pid;
3825e96ac45SJed Brown         args[j++] = program;
383493de400SSatish Balay #else
384493de400SSatish Balay         args[j++] = program;
385493de400SSatish Balay         args[j++] = pid;
3868d359177SBarry Smith #endif
38702c9f0b5SLisandro Dalcin         args[j++] = NULL;
388e5c89e4eSSatish Balay       }
389*c823fc1fSBarry Smith       if (UseDebugTerminal) {
390c5888dd7SBarry 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);
391c5888dd7SBarry Smith         else            printf("PETSC: Attaching %s to %s on pid %s on %s\n",PetscDebugger,program,pid,hostname);
392a297a907SKarl Rupp 
3935e96ac45SJed Brown         if (execvp(args[0],(char**)args)  < 0) {
3945e96ac45SJed Brown           perror("Unable to start debugger in xterm");
3955e96ac45SJed Brown           exit(0);
3965e96ac45SJed Brown         }
3975e96ac45SJed Brown       } else {
398c5888dd7SBarry Smith         printf("PETSC: Attaching %s to %s of pid %s on %s\n",PetscDebugger,program,pid,hostname);
399e5c89e4eSSatish Balay         if (execvp(args[0],(char**)args)  < 0) {
400e5c89e4eSSatish Balay           perror("Unable to start debugger");
401e5c89e4eSSatish Balay           exit(0);
402e5c89e4eSSatish Balay         }
403e5c89e4eSSatish Balay       }
404e5c89e4eSSatish Balay     }
405e5c89e4eSSatish Balay   } else {   /* I am the child, continue with user code */
406e5c89e4eSSatish Balay     sleeptime = 10; /* default to sleep waiting for debugger */
407c5929fdfSBarry Smith     ierr = PetscOptionsGetReal(NULL,NULL,"-debugger_pause",&sleeptime,NULL);CHKERRQ(ierr);
408e5c89e4eSSatish Balay     if (sleeptime < 0) sleeptime = -sleeptime;
409e5c89e4eSSatish Balay #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP)
410e5c89e4eSSatish Balay     /*
411e5c89e4eSSatish Balay         HP cannot attach process to sleeping debugger, hence count instead
412e5c89e4eSSatish Balay     */
413e5c89e4eSSatish Balay     {
414e5c89e4eSSatish Balay       PetscReal x = 1.0;
415e5c89e4eSSatish Balay       int       i =10000000;
416e5c89e4eSSatish Balay       while (i--) x++;  /* cannot attach to sleeper */
417e5c89e4eSSatish Balay     }
418e5c89e4eSSatish Balay #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY)
419e5c89e4eSSatish Balay     /*
420e5c89e4eSSatish Balay         IBM sleep may return at anytime, hence must see if there is more time to sleep
421e5c89e4eSSatish Balay     */
422e5c89e4eSSatish Balay     {
423e5c89e4eSSatish Balay       int left = sleeptime;
424a297a907SKarl Rupp       while (left > 0) left = PetscSleep(left) - 1;
425e5c89e4eSSatish Balay     }
426e5c89e4eSSatish Balay #else
427e5c89e4eSSatish Balay     PetscSleep(sleeptime);
428e5c89e4eSSatish Balay #endif
429e5c89e4eSSatish Balay   }
430e5c89e4eSSatish Balay #endif
431e5c89e4eSSatish Balay   PetscFunctionReturn(0);
432e5c89e4eSSatish Balay }
433e5c89e4eSSatish Balay 
434e5c89e4eSSatish Balay /*@C
435e5c89e4eSSatish Balay    PetscAttachDebuggerErrorHandler - Error handler that attaches
436e5c89e4eSSatish Balay    a debugger to a running process when an error is detected.
437e5c89e4eSSatish Balay    This routine is useful for examining variables, etc.
438e5c89e4eSSatish Balay 
439e5c89e4eSSatish Balay    Not Collective
440e5c89e4eSSatish Balay 
441e5c89e4eSSatish Balay    Input Parameters:
442e32f2f54SBarry Smith +  comm - communicator over which error occurred
443e32f2f54SBarry Smith .  line - the line number of the error (indicated by __LINE__)
444e5c89e4eSSatish Balay .  file - the file in which the error was detected (indicated by __FILE__)
445e5c89e4eSSatish Balay .  message - an error text string, usually just printed to the screen
446e5c89e4eSSatish Balay .  number - the generic error number
447668f157eSBarry Smith .  p - PETSC_ERROR_INITIAL if error just detected, otherwise PETSC_ERROR_REPEAT
448e5c89e4eSSatish Balay -  ctx - error handler context
449e5c89e4eSSatish Balay 
450e5c89e4eSSatish Balay    Options Database Keys:
45145b666d6SBarry Smith +  -on_error_attach_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] - Activates debugger attachment
45245b666d6SBarry Smith -  -start_in_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] [-debugger_ranks m,n]
453e5c89e4eSSatish Balay 
454e5c89e4eSSatish Balay    Level: developer
455e5c89e4eSSatish Balay 
456e5c89e4eSSatish Balay    Notes:
457c4fb7a8fSRichard Tran Mills    By default the GNU debugger, gdb, is used.  Alternatives are cuda-gdb, lldb, dbx and
458e5c89e4eSSatish Balay    xxgdb,xldb (on IBM rs6000), xdb (on HP-UX).
459e5c89e4eSSatish Balay 
460e5c89e4eSSatish Balay    Most users need not directly employ this routine and the other error
461e5c89e4eSSatish Balay    handlers, but can instead use the simplified interface SETERR, which has
462e5c89e4eSSatish Balay    the calling sequence
463e32f2f54SBarry Smith $     SETERRQ(PETSC_COMM_SELF,number,p,message)
464e5c89e4eSSatish Balay 
465e5c89e4eSSatish Balay    Notes for experienced users:
466e5c89e4eSSatish Balay    Use PetscPushErrorHandler() to set the desired error handler.  The
467e5c89e4eSSatish Balay    currently available PETSc error handlers are
468e5c89e4eSSatish Balay $    PetscTraceBackErrorHandler()
469e5c89e4eSSatish Balay $    PetscAttachDebuggerErrorHandler()
470e5c89e4eSSatish Balay $    PetscAbortErrorHandler()
471e5c89e4eSSatish Balay    or you may write your own.
472e5c89e4eSSatish Balay 
473e5c89e4eSSatish Balay 
47445b666d6SBarry Smith .seealso:  PetscSetDebuggerFromString(), PetscSetDebugger(), PetscSetDefaultDebugger(), PetscError(), PetscPushErrorHandler(), PetscPopErrorHandler(), PetscTraceBackErrorHandler(),
475*c823fc1fSBarry Smith            PetscAbortErrorHandler(), PetscMPIAbortErrorHandler(), PetscEmacsClientErrorHandler(), PetscReturnErrorHandler(), PetscSetDebugTermainal()
476e5c89e4eSSatish Balay @*/
477efca3c55SSatish Balay PetscErrorCode  PetscAttachDebuggerErrorHandler(MPI_Comm comm,int line,const char *fun,const char *file,PetscErrorCode num,PetscErrorType p,const char *mess,void *ctx)
478e5c89e4eSSatish Balay {
479e5c89e4eSSatish Balay   PetscErrorCode ierr;
480e5c89e4eSSatish Balay 
481e5c89e4eSSatish Balay   PetscFunctionBegin;
482e5c89e4eSSatish Balay   if (!fun) fun = "User provided function";
483e5c89e4eSSatish Balay   if (!mess) mess = " ";
484e5c89e4eSSatish Balay 
485efca3c55SSatish Balay   (*PetscErrorPrintf)("%s() line %d in %s %s\n",fun,line,file,mess);
486e5c89e4eSSatish Balay 
487e5c89e4eSSatish Balay   ierr = PetscAttachDebugger();
488a297a907SKarl Rupp   if (ierr) abort(); /* call abort because don't want to kill other MPI processes that may successfully attach to debugger */
489e5c89e4eSSatish Balay   PetscFunctionReturn(0);
490e5c89e4eSSatish Balay }
491e5c89e4eSSatish Balay 
492e5c89e4eSSatish Balay /*@C
493e5c89e4eSSatish Balay    PetscStopForDebugger - Prints a message to the screen indicating how to
494e5c89e4eSSatish Balay          attach to the process with the debugger and then waits for the
495e5c89e4eSSatish Balay          debugger to attach.
496e5c89e4eSSatish Balay 
497e5c89e4eSSatish Balay    Not Collective
498e5c89e4eSSatish Balay 
4998d359177SBarry Smith    Level: developer
500e5c89e4eSSatish Balay 
50195452b02SPatrick Sanan    Notes:
50295452b02SPatrick Sanan     This is likely never needed since PetscAttachDebugger() is easier to use and seems to always work.
5038d359177SBarry Smith 
50495452b02SPatrick Sanan    Developer Notes:
50595452b02SPatrick Sanan     Since this can be called by the error handler, should it be calling SETERRQ() and CHKERRQ()?
506f35f84d1SBarry Smith 
507e5c89e4eSSatish Balay .seealso: PetscSetDebugger(), PetscAttachDebugger()
508e5c89e4eSSatish Balay @*/
5097087cfbeSBarry Smith PetscErrorCode  PetscStopForDebugger(void)
510e5c89e4eSSatish Balay {
511e5c89e4eSSatish Balay   PetscErrorCode ierr;
512e5c89e4eSSatish Balay   PetscInt       sleeptime=0;
513e5c89e4eSSatish Balay #if !defined(PETSC_CANNOT_START_DEBUGGER)
51451ec2c11SGlenn Hammond   int            ppid;
515e5c89e4eSSatish Balay   PetscMPIInt    rank;
516e5c89e4eSSatish Balay   char           program[PETSC_MAX_PATH_LEN],hostname[256];
5178d359177SBarry Smith   PetscBool      isdbx,isxldb,isxxgdb,isddd,iskdbg,isups,isxdb,islldb;
518e5c89e4eSSatish Balay #endif
519e5c89e4eSSatish Balay 
520e5c89e4eSSatish Balay   PetscFunctionBegin;
521e5c89e4eSSatish Balay #if defined(PETSC_CANNOT_START_DEBUGGER)
522e5c89e4eSSatish Balay   (*PetscErrorPrintf)("System cannot start debugger; just continuing program\n");
523e5c89e4eSSatish Balay #else
524e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
525f35f84d1SBarry Smith   if (ierr) rank = 0; /* ignore error since this may be already in error handler */
526589a23caSBarry Smith   ierr = PetscGetHostName(hostname,sizeof(hostname));
527e5c89e4eSSatish Balay   if (ierr) {
528e5c89e4eSSatish Balay     (*PetscErrorPrintf)("Cannot determine hostname; just continuing program\n");
529e5c89e4eSSatish Balay     PetscFunctionReturn(0);
530e5c89e4eSSatish Balay   }
531e5c89e4eSSatish Balay 
532589a23caSBarry Smith   ierr = PetscGetProgramName(program,sizeof(program));
533e5c89e4eSSatish Balay   if (ierr) {
534e5c89e4eSSatish Balay     (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n");
535e5c89e4eSSatish Balay     PetscFunctionReturn(0);
536e5c89e4eSSatish Balay   }
537e5c89e4eSSatish Balay   if (!program[0]) {
538e5c89e4eSSatish Balay     (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n");
539e5c89e4eSSatish Balay     PetscFunctionReturn(0);
540e5c89e4eSSatish Balay   }
541e5c89e4eSSatish Balay 
542e5c89e4eSSatish Balay   ppid = getpid();
543e5c89e4eSSatish Balay 
544b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"xxgdb",&isxxgdb);CHKERRQ(ierr);
545b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"ddd",&isddd);CHKERRQ(ierr);
546b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"kdbg",&iskdbg);CHKERRQ(ierr);
547b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"ups",&isups);CHKERRQ(ierr);
548b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"xldb",&isxldb);CHKERRQ(ierr);
549b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"xdb",&isxdb);CHKERRQ(ierr);
550b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"dbx",&isdbx);CHKERRQ(ierr);
551b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"lldb",&islldb);CHKERRQ(ierr);
552e5c89e4eSSatish Balay 
553c5888dd7SBarry Smith   if (isxxgdb || isups || isddd || iskdbg) printf("[%d]%s>>%s %s %d\n",rank,hostname,PetscDebugger,program,ppid);
554c5888dd7SBarry Smith   else if (isxldb) printf("[%d]%s>>%s -a %d %s\n",rank,hostname,PetscDebugger,ppid,program);
555c5888dd7SBarry Smith   else if (islldb) printf("[%d]%s>>%s -p %d\n",rank,hostname,PetscDebugger,ppid);
5568d359177SBarry Smith   else if (isdbx) {
557e5c89e4eSSatish Balay #if defined(PETSC_USE_P_FOR_DEBUGGER)
558c5888dd7SBarry Smith      printf("[%d]%s>>%s -p %d %s\n",rank,hostname,PetscDebugger,ppid,program);
559e5c89e4eSSatish Balay #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER)
560c5888dd7SBarry Smith      printf("[%d]%s>>%s -l ALL -P %d %s\n",rank,hostname,PetscDebugger,ppid,program);
561e5c89e4eSSatish Balay #elif defined(PETSC_USE_A_FOR_DEBUGGER)
562c5888dd7SBarry Smith      printf("[%d]%s>>%s -a %d\n",rank,hostname,PetscDebugger,ppid);
563e5c89e4eSSatish Balay #elif defined(PETSC_USE_PID_FOR_DEBUGGER)
564c5888dd7SBarry Smith      printf("[%d]%s>>%s -pid %d %s\n",rank,hostname,PetscDebugger,ppid,program);
565e5c89e4eSSatish Balay #else
566c5888dd7SBarry Smith      printf("[%d]%s>>%s %s %d\n",rank,hostname,PetscDebugger,program,ppid);
567e5c89e4eSSatish Balay #endif
5688d359177SBarry Smith   }
569e5c89e4eSSatish Balay #endif /* PETSC_CANNOT_START_DEBUGGER */
570e5c89e4eSSatish Balay 
571f35f84d1SBarry Smith   fflush(stdout); /* ignore error because may already be in error handler */
572e5c89e4eSSatish Balay 
573e5c89e4eSSatish Balay   sleeptime = 25; /* default to sleep waiting for debugger */
574c5929fdfSBarry Smith   PetscOptionsGetInt(NULL,NULL,"-debugger_pause",&sleeptime,NULL); /* ignore error because may already be in error handler */
575e5c89e4eSSatish Balay   if (sleeptime < 0) sleeptime = -sleeptime;
576e5c89e4eSSatish Balay #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP)
577e5c89e4eSSatish Balay   /*
578e5c89e4eSSatish Balay       HP cannot attach process to sleeping debugger, hence count instead
579e5c89e4eSSatish Balay   */
580e5c89e4eSSatish Balay   {
581e5c89e4eSSatish Balay     PetscReal x = 1.0;
582e5c89e4eSSatish Balay     int       i =10000000;
583e5c89e4eSSatish Balay     while (i--) x++;  /* cannot attach to sleeper */
584e5c89e4eSSatish Balay   }
585e5c89e4eSSatish Balay #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY)
586e5c89e4eSSatish Balay   /*
587e5c89e4eSSatish Balay       IBM sleep may return at anytime, hence must see if there is more time to sleep
588e5c89e4eSSatish Balay   */
589e5c89e4eSSatish Balay   {
590e5c89e4eSSatish Balay     int left = sleeptime;
591a297a907SKarl Rupp     while (left > 0) left = sleep(left) - 1;
592e5c89e4eSSatish Balay   }
593e5c89e4eSSatish Balay #else
594e5c89e4eSSatish Balay   PetscSleep(sleeptime);
595e5c89e4eSSatish Balay #endif
596e5c89e4eSSatish Balay   PetscFunctionReturn(0);
597e5c89e4eSSatish Balay }
598