xref: /petsc/src/sys/error/adebug.c (revision a2b725a8db0d6bf6cc2a1c6df7dd8029aadfff6e)
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];
16ace3abfcSBarry Smith static PetscBool Xterm = PETSC_TRUE;
17e5c89e4eSSatish Balay 
185e96ac45SJed Brown /*@C
195e96ac45SJed Brown    PetscSetDebugTerminal - Sets the terminal to use (instead of xterm) for debugging.
205e96ac45SJed Brown 
215e96ac45SJed Brown    Not Collective
225e96ac45SJed Brown 
235e96ac45SJed Brown    Input Parameters:
24*a2b725a8SWilliam Gropp .  terminal - name of terminal and any flags required to execute a program.
25a5ba6984SMatthew G. Knepley               For example "xterm -e", "urxvt -e", "gnome-terminal -x".
265e96ac45SJed Brown 
275e96ac45SJed Brown    Options Database Keys:
285e96ac45SJed Brown    -debug_terminal terminal - use this terminal instead of xterm
295e96ac45SJed Brown 
305e96ac45SJed Brown    Level: developer
315e96ac45SJed Brown 
325e96ac45SJed Brown    Notes:
335e96ac45SJed Brown    You can start the debugger for all processes in the same GNU screen session.
345e96ac45SJed Brown 
35a6404fbfSBarry Smith      mpiexec -n 4 ./myapp -start_in_debugger -debug_terminal "screen -X -S debug screen"
365e96ac45SJed Brown 
375e96ac45SJed Brown    will open 4 windows in the session named "debug".
385e96ac45SJed Brown 
395e96ac45SJed Brown    Fortran Note:
405e96ac45SJed Brown    This routine is not supported in Fortran.
415e96ac45SJed Brown 
425e96ac45SJed Brown    Concepts: debugger^setting
435e96ac45SJed Brown 
445e96ac45SJed Brown .seealso: PetscSetDebugger()
455e96ac45SJed Brown @*/
467087cfbeSBarry Smith PetscErrorCode  PetscSetDebugTerminal(const char terminal[])
475e96ac45SJed Brown {
485e96ac45SJed Brown   PetscErrorCode ierr;
495e96ac45SJed Brown 
505e96ac45SJed Brown   PetscFunctionBegin;
515e96ac45SJed Brown   ierr = PetscStrcpy(DebugTerminal,terminal);CHKERRQ(ierr);
525e96ac45SJed Brown   PetscFunctionReturn(0);
535e96ac45SJed Brown }
545e96ac45SJed Brown 
55e5c89e4eSSatish Balay /*@C
56e5c89e4eSSatish Balay    PetscSetDebugger - Sets options associated with the debugger.
57e5c89e4eSSatish Balay 
58e5c89e4eSSatish Balay    Not Collective
59e5c89e4eSSatish Balay 
60e5c89e4eSSatish Balay    Input Parameters:
61e5c89e4eSSatish Balay +  debugger - name of debugger, which should be in your path,
628d359177SBarry Smith               usually "lldb", "dbx", "gdb", "idb", "xxgdb", "kdgb" or "ddd". Also, HP-UX
63e5c89e4eSSatish Balay               supports "xdb", and IBM rs6000 supports "xldb".
64e5c89e4eSSatish Balay 
658d359177SBarry Smith -  xterm - flag to indicate debugger window, set to either PETSC_TRUE (to indicate
668d359177SBarry Smith             debugger should be started in a new xterm) or PETSC_FALSE (to start debugger
678d359177SBarry Smith             in initial window (the option PETSC_FALSE makes no sense when using more
688d359177SBarry Smith             than one MPI process.)
69e5c89e4eSSatish Balay 
70e5c89e4eSSatish Balay    Level: developer
71e5c89e4eSSatish Balay 
72e5c89e4eSSatish Balay    Fortran Note:
73e5c89e4eSSatish Balay    This routine is not supported in Fortran.
74e5c89e4eSSatish Balay 
75e5c89e4eSSatish Balay   Concepts: debugger^setting
76e5c89e4eSSatish Balay 
77e5c89e4eSSatish Balay .seealso: PetscAttachDebugger(), PetscAttachDebuggerErrorHandler()
78e5c89e4eSSatish Balay @*/
797087cfbeSBarry Smith PetscErrorCode  PetscSetDebugger(const char debugger[],PetscBool xterm)
80e5c89e4eSSatish Balay {
81e5c89e4eSSatish Balay   PetscErrorCode ierr;
82e5c89e4eSSatish Balay 
83e5c89e4eSSatish Balay   PetscFunctionBegin;
84e5c89e4eSSatish Balay   if (debugger) {
85b59f628eSBarry Smith     ierr = PetscStrcpy(PetscDebugger,debugger);CHKERRQ(ierr);
86e5c89e4eSSatish Balay   }
87e5c89e4eSSatish Balay   Xterm = xterm;
88e5c89e4eSSatish Balay   PetscFunctionReturn(0);
89e5c89e4eSSatish Balay }
90e5c89e4eSSatish Balay 
918d359177SBarry Smith /*@C
92f35f84d1SBarry Smith     PetscSetDefaultDebugger - Causes PETSc to use its default  debugger.
93e5c89e4eSSatish Balay 
94e5c89e4eSSatish Balay    Not collective
95e5c89e4eSSatish Balay 
968d359177SBarry Smith     Level: developer
97e5c89e4eSSatish Balay 
98e5c89e4eSSatish Balay .seealso: PetscSetDebugger(), PetscSetDebuggerFromString()
99e5c89e4eSSatish Balay @*/
1007087cfbeSBarry Smith PetscErrorCode  PetscSetDefaultDebugger(void)
101e5c89e4eSSatish Balay {
102e5c89e4eSSatish Balay   PetscErrorCode ierr;
103e5c89e4eSSatish Balay 
104e5c89e4eSSatish Balay   PetscFunctionBegin;
1058d359177SBarry Smith #if defined(PETSC_USE_LLDB_DEBUGGER)
1068d359177SBarry Smith   ierr = PetscSetDebugger("lldb",PETSC_TRUE);CHKERRQ(ierr);
1078d359177SBarry Smith #elif defined(PETSC_USE_DBX_DEBUGGER)
108e5c89e4eSSatish Balay   ierr = PetscSetDebugger("dbx",PETSC_TRUE);CHKERRQ(ierr);
109e5c89e4eSSatish Balay #elif defined(PETSC_USE_XDB_DEBUGGER)
110e5c89e4eSSatish Balay   ierr = PetscSetDebugger("xdb",PETSC_TRUE);CHKERRQ(ierr);
111e5c89e4eSSatish Balay #elif defined(PETSC_USE_IDB_DEBUGGER)
112e5c89e4eSSatish Balay   ierr = PetscSetDebugger("idb",PETSC_TRUE);CHKERRQ(ierr);
113e5c89e4eSSatish Balay #else  /* Default is gdb */
114e5c89e4eSSatish Balay   ierr = PetscSetDebugger("gdb",PETSC_TRUE);CHKERRQ(ierr);
115e5c89e4eSSatish Balay #endif
1165e96ac45SJed Brown   ierr = PetscSetDebugTerminal("xterm -e");CHKERRQ(ierr);
117e5c89e4eSSatish Balay   PetscFunctionReturn(0);
118e5c89e4eSSatish Balay }
119e5c89e4eSSatish Balay 
120e5c89e4eSSatish Balay static PetscErrorCode PetscCheckDebugger_Private(const char defaultDbg[], const char string[], const char *debugger[])
121e5c89e4eSSatish Balay {
122ace3abfcSBarry Smith   PetscBool      exists;
123e5c89e4eSSatish Balay   char           *f;
124e5c89e4eSSatish Balay   PetscErrorCode ierr;
125e5c89e4eSSatish Balay 
126e5c89e4eSSatish Balay   PetscFunctionBegin;
127e5c89e4eSSatish Balay   ierr = PetscStrstr(string, defaultDbg, &f);CHKERRQ(ierr);
128e5c89e4eSSatish Balay   if (f) {
129e5c89e4eSSatish Balay     ierr = PetscTestFile(string, 'x', &exists);CHKERRQ(ierr);
130a297a907SKarl Rupp     if (exists) *debugger = string;
131a297a907SKarl Rupp     else        *debugger = defaultDbg;
132e5c89e4eSSatish Balay   }
133e5c89e4eSSatish Balay   PetscFunctionReturn(0);
134e5c89e4eSSatish Balay }
135e5c89e4eSSatish Balay 
136e5c89e4eSSatish Balay /*@C
137e5c89e4eSSatish Balay     PetscSetDebuggerFromString - Set the complete path for the
138e5c89e4eSSatish Balay        debugger for PETSc to use.
139e5c89e4eSSatish Balay 
140e5c89e4eSSatish Balay    Not collective
141e5c89e4eSSatish Balay 
1427c764164SBarry Smith    Level: developer
143e5c89e4eSSatish Balay 
144e5c89e4eSSatish Balay .seealso: PetscSetDebugger(), PetscSetDefaultDebugger()
145e5c89e4eSSatish Balay @*/
1467c764164SBarry Smith PetscErrorCode  PetscSetDebuggerFromString(const char *string)
147e5c89e4eSSatish Balay {
1480298fd71SBarry Smith   const char     *debugger = NULL;
149ace3abfcSBarry Smith   PetscBool      xterm     = PETSC_TRUE;
150e5c89e4eSSatish Balay   char           *f;
151e5c89e4eSSatish Balay   PetscErrorCode ierr;
152e5c89e4eSSatish Balay 
153e5c89e4eSSatish Balay   PetscFunctionBegin;
154e5c89e4eSSatish Balay   ierr = PetscStrstr(string, "noxterm", &f);CHKERRQ(ierr);
155e5c89e4eSSatish Balay   if (f) xterm = PETSC_FALSE;
156e5c89e4eSSatish Balay   ierr = PetscStrstr(string, "ddd", &f);CHKERRQ(ierr);
157e5c89e4eSSatish Balay   if (f) xterm = PETSC_FALSE;
158e5c89e4eSSatish Balay   ierr = PetscCheckDebugger_Private("xdb",      string, &debugger);CHKERRQ(ierr);
159e5c89e4eSSatish Balay   ierr = PetscCheckDebugger_Private("dbx",      string, &debugger);CHKERRQ(ierr);
160e5c89e4eSSatish Balay   ierr = PetscCheckDebugger_Private("xldb",     string, &debugger);CHKERRQ(ierr);
161e5c89e4eSSatish Balay   ierr = PetscCheckDebugger_Private("gdb",      string, &debugger);CHKERRQ(ierr);
162e5c89e4eSSatish Balay   ierr = PetscCheckDebugger_Private("idb",      string, &debugger);CHKERRQ(ierr);
163e5c89e4eSSatish Balay   ierr = PetscCheckDebugger_Private("xxgdb",    string, &debugger);CHKERRQ(ierr);
164e5c89e4eSSatish Balay   ierr = PetscCheckDebugger_Private("ddd",      string, &debugger);CHKERRQ(ierr);
165bf902449SSatish Balay   ierr = PetscCheckDebugger_Private("kdbg",     string, &debugger);CHKERRQ(ierr);
166e5c89e4eSSatish Balay   ierr = PetscCheckDebugger_Private("ups",      string, &debugger);CHKERRQ(ierr);
167e5c89e4eSSatish Balay   ierr = PetscCheckDebugger_Private("workshop", string, &debugger);CHKERRQ(ierr);
168e5c89e4eSSatish Balay   ierr = PetscCheckDebugger_Private("pgdbg",    string, &debugger);CHKERRQ(ierr);
169ecbcaa78SBarry Smith   ierr = PetscCheckDebugger_Private("pathdb",   string, &debugger);CHKERRQ(ierr);
1700e9bae81SBarry Smith   ierr = PetscCheckDebugger_Private("lldb",     string, &debugger);CHKERRQ(ierr);
171e5c89e4eSSatish Balay 
172e5c89e4eSSatish Balay   ierr = PetscSetDebugger(debugger, xterm);CHKERRQ(ierr);
173e5c89e4eSSatish Balay   PetscFunctionReturn(0);
174e5c89e4eSSatish Balay }
175e5c89e4eSSatish Balay 
176e5c89e4eSSatish Balay 
177e30d2299SSatish Balay /*@
178e5c89e4eSSatish Balay    PetscAttachDebugger - Attaches the debugger to the running process.
179e5c89e4eSSatish Balay 
180e5c89e4eSSatish Balay    Not Collective
181e5c89e4eSSatish Balay 
182e5c89e4eSSatish Balay    Level: advanced
183e5c89e4eSSatish Balay 
184e5c89e4eSSatish Balay    Concepts: debugger^starting from program
185e5c89e4eSSatish Balay 
18695452b02SPatrick Sanan    Developer Notes:
18795452b02SPatrick Sanan     Since this can be called by the error handler should it be calling SETERRQ() and CHKERRQ()?
188f35f84d1SBarry Smith 
189e5c89e4eSSatish Balay .seealso: PetscSetDebugger()
190e5c89e4eSSatish Balay @*/
1917087cfbeSBarry Smith PetscErrorCode  PetscAttachDebugger(void)
192e5c89e4eSSatish Balay {
193e5c89e4eSSatish Balay #if !defined(PETSC_CANNOT_START_DEBUGGER)
194e5c89e4eSSatish Balay   int            child    =0;
195a6d0e24fSJed Brown   PetscReal      sleeptime=0;
196e5c89e4eSSatish Balay   PetscErrorCode ierr;
197e5c89e4eSSatish Balay   char           program[PETSC_MAX_PATH_LEN],display[256],hostname[64];
198e5c89e4eSSatish Balay #endif
199e5c89e4eSSatish Balay 
200e5c89e4eSSatish Balay   PetscFunctionBegin;
201e5c89e4eSSatish Balay #if defined(PETSC_CANNOT_START_DEBUGGER) || !defined(PETSC_HAVE_FORK)
202e5c89e4eSSatish Balay   (*PetscErrorPrintf)("System cannot start debugger\n");
203e5c89e4eSSatish Balay   (*PetscErrorPrintf)("On Cray run program in Totalview debugger\n");
204e5c89e4eSSatish Balay   (*PetscErrorPrintf)("On Windows use Developer Studio(MSDEV)\n");
205fa6b8e38SSatish Balay   MPI_Abort(PETSC_COMM_WORLD,1);
206e5c89e4eSSatish Balay #else
207e5c89e4eSSatish Balay   ierr = PetscGetDisplay(display,128);CHKERRQ(ierr);
208e5c89e4eSSatish Balay   ierr = PetscGetProgramName(program,PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
209e5c89e4eSSatish Balay   if (ierr) {
210e5c89e4eSSatish Balay     (*PetscErrorPrintf)("Cannot determine program name\n");
211e5c89e4eSSatish Balay     PetscFunctionReturn(1);
212e5c89e4eSSatish Balay   }
213e5c89e4eSSatish Balay   if (!program[0]) {
214e5c89e4eSSatish Balay     (*PetscErrorPrintf)("Cannot determine program name\n");
215e5c89e4eSSatish Balay     PetscFunctionReturn(1);
216e5c89e4eSSatish Balay   }
217e5c89e4eSSatish Balay   child = (int)fork();
218e5c89e4eSSatish Balay   if (child < 0) {
219e5c89e4eSSatish Balay     (*PetscErrorPrintf)("Error in fork() attaching debugger\n");
220e5c89e4eSSatish Balay     PetscFunctionReturn(1);
221e5c89e4eSSatish Balay   }
222e5c89e4eSSatish Balay 
223e5c89e4eSSatish Balay   /*
224e5c89e4eSSatish Balay       Swap role the parent and child. This is (I think) so that control c typed
225e5c89e4eSSatish Balay     in the debugger goes to the correct process.
226e5c89e4eSSatish Balay   */
227a297a907SKarl Rupp   if (child) child = 0;
228a297a907SKarl Rupp   else       child = (int)getppid();
229e5c89e4eSSatish Balay 
230e5c89e4eSSatish Balay   if (child) { /* I am the parent, will run the debugger */
231e5c89e4eSSatish Balay     const char *args[10];
232e5c89e4eSSatish Balay     char       pid[10];
2335e96ac45SJed Brown     PetscInt   j,jj;
2340e9bae81SBarry Smith     PetscBool  isdbx,isidb,isxldb,isxxgdb,isups,isxdb,isworkshop,isddd,iskdbg,islldb;
235e5c89e4eSSatish Balay 
236e5c89e4eSSatish Balay     ierr = PetscGetHostName(hostname,64);CHKERRQ(ierr);
237e5c89e4eSSatish Balay     /*
238e5c89e4eSSatish Balay          We need to send a continue signal to the "child" process on the
239e5c89e4eSSatish Balay        alpha, otherwise it just stays off forever
240e5c89e4eSSatish Balay     */
241e5c89e4eSSatish Balay #if defined(PETSC_NEED_KILL_FOR_DEBUGGER)
242e5c89e4eSSatish Balay     kill(child,SIGCONT);
243e5c89e4eSSatish Balay #endif
244e5c89e4eSSatish Balay     sprintf(pid,"%d",child);
245e5c89e4eSSatish Balay 
246b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"xxgdb",&isxxgdb);CHKERRQ(ierr);
247b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"ddd",&isddd);CHKERRQ(ierr);
248b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"kdbg",&iskdbg);CHKERRQ(ierr);
249b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"ups",&isups);CHKERRQ(ierr);
250b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"xldb",&isxldb);CHKERRQ(ierr);
251b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"xdb",&isxdb);CHKERRQ(ierr);
252b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"dbx",&isdbx);CHKERRQ(ierr);
253b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"idb",&isidb);CHKERRQ(ierr);
254b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"workshop",&isworkshop);CHKERRQ(ierr);
255b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"lldb",&islldb);CHKERRQ(ierr);
256e5c89e4eSSatish Balay 
257e5c89e4eSSatish Balay     if (isxxgdb || isups || isddd) {
258e5c89e4eSSatish Balay       args[1] = program; args[2] = pid; args[3] = "-display";
259b59f628eSBarry Smith       args[0] = PetscDebugger; args[4] = display; args[5] = 0;
260c5888dd7SBarry Smith       printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname);
261e5c89e4eSSatish Balay       if (execvp(args[0],(char**)args)  < 0) {
262e5c89e4eSSatish Balay         perror("Unable to start debugger");
263e5c89e4eSSatish Balay         exit(0);
264e5c89e4eSSatish Balay       }
265bf902449SSatish Balay     } else if (iskdbg) {
266bf902449SSatish Balay       args[1] = "-p"; args[2] = pid; args[3] = program;  args[4] = "-display";
267b59f628eSBarry Smith       args[0] = PetscDebugger; args[5] = display; args[6] = 0;
268c5888dd7SBarry Smith       printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[3],pid,hostname);
269bf902449SSatish Balay       if (execvp(args[0],(char**)args)  < 0) {
270bf902449SSatish Balay         perror("Unable to start debugger");
271bf902449SSatish Balay         exit(0);
272bf902449SSatish Balay       }
273e5c89e4eSSatish Balay     } else if (isxldb) {
274e5c89e4eSSatish Balay       args[1] = "-a"; args[2] = pid; args[3] = program;  args[4] = "-display";
275b59f628eSBarry Smith       args[0] = PetscDebugger; args[5] = display; args[6] = 0;
276c5888dd7SBarry Smith       printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname);
277e5c89e4eSSatish Balay       if (execvp(args[0],(char**)args)  < 0) {
278e5c89e4eSSatish Balay         perror("Unable to start debugger");
279e5c89e4eSSatish Balay         exit(0);
280e5c89e4eSSatish Balay       }
281e5c89e4eSSatish Balay     } else if (isworkshop) {
282e5c89e4eSSatish Balay       args[1] = "-s"; args[2] = pid; args[3] = "-D"; args[4] = "-";
283b59f628eSBarry Smith       args[0] = PetscDebugger; args[5] = pid; args[6] = "-display"; args[7] = display; args[8] = 0;
284c5888dd7SBarry Smith       printf("PETSC: Attaching %s to %s on %s\n",args[0],pid,hostname);
285e5c89e4eSSatish Balay       if (execvp(args[0],(char**)args)  < 0) {
286e5c89e4eSSatish Balay         perror("Unable to start debugger");
287e5c89e4eSSatish Balay         exit(0);
288e5c89e4eSSatish Balay       }
2895e96ac45SJed Brown     } else {
2905e96ac45SJed Brown       j = 0;
2915e96ac45SJed Brown       if (Xterm) {
292ace3abfcSBarry Smith         PetscBool cmp;
2935e96ac45SJed Brown         char      *tmp,*tmp1;
2945e96ac45SJed Brown         ierr = PetscStrncmp(DebugTerminal,"screen",6,&cmp);CHKERRQ(ierr);
295a5ba6984SMatthew G. Knepley         if (!cmp) {ierr = PetscStrncmp(DebugTerminal,"gnome-terminal",6,&cmp);CHKERRQ(ierr);}
2965e96ac45SJed Brown         if (cmp) display[0] = 0; /* when using screen, we never pass -display */
2975e96ac45SJed Brown         args[j++] = tmp = DebugTerminal;
2985e96ac45SJed Brown         if (display[0]) {
2995e96ac45SJed Brown           args[j++] = "-display"; args[j++] = display;
3005e96ac45SJed Brown         }
3015e96ac45SJed Brown         while (*tmp) {
3025e96ac45SJed Brown           ierr = PetscStrchr(tmp,' ',&tmp1);CHKERRQ(ierr);
3035e96ac45SJed Brown           if (!tmp1) break;
3045e96ac45SJed Brown           *tmp1     = 0;
3055e96ac45SJed Brown           tmp       = tmp1+1;
3065e96ac45SJed Brown           args[j++] = tmp;
3075e96ac45SJed Brown         }
3085e96ac45SJed Brown       }
309b59f628eSBarry Smith       args[j++] = PetscDebugger;
3105e96ac45SJed Brown       jj = j;
3115e96ac45SJed Brown       args[j++] = program; args[j++] = pid; args[j++] = 0;
3125e96ac45SJed Brown 
313e5c89e4eSSatish Balay       if (isidb) {
3145e96ac45SJed Brown         j = jj;
3155e96ac45SJed Brown         args[j++] = "-pid";
3165e96ac45SJed Brown         args[j++] = pid;
3175e96ac45SJed Brown         args[j++] = "-gdb";
3185e96ac45SJed Brown         args[j++] = program;
3195e96ac45SJed Brown         args[j++] = 0;
320e5c89e4eSSatish Balay       }
3210e9bae81SBarry Smith       if (islldb) {
3220e9bae81SBarry Smith         j = jj;
3230e9bae81SBarry Smith         args[j++] = "-p";
3240e9bae81SBarry Smith         args[j++] = pid;
3250e9bae81SBarry Smith         args[j++] = 0;
3260e9bae81SBarry Smith       }
327e5c89e4eSSatish Balay       if (isdbx) {
3285e96ac45SJed Brown         j = jj;
3298d359177SBarry Smith #if defined(PETSC_USE_P_FOR_DEBUGGER)
3305e96ac45SJed Brown         args[j++] = "-p";
3315e96ac45SJed Brown         args[j++] = pid;
3325e96ac45SJed Brown         args[j++] = program;
333e5c89e4eSSatish Balay #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER)
3345e96ac45SJed Brown         args[j++] = "-l";
3355e96ac45SJed Brown         args[j++] = "ALL";
3365e96ac45SJed Brown         args[j++] = "-P";
3375e96ac45SJed Brown         args[j++] = pid;
3385e96ac45SJed Brown         args[j++] = program;
339e5c89e4eSSatish Balay #elif defined(PETSC_USE_A_FOR_DEBUGGER)
3405e96ac45SJed Brown         args[j++] = "-a";
3415e96ac45SJed Brown         args[j++] = pid;
342e5c89e4eSSatish Balay #elif defined(PETSC_USE_PID_FOR_DEBUGGER)
3435e96ac45SJed Brown         args[j++] = "-pid";
3445e96ac45SJed Brown         args[j++] = pid;
3455e96ac45SJed Brown         args[j++] = program;
346493de400SSatish Balay #else
347493de400SSatish Balay         args[j++] = program;
348493de400SSatish Balay         args[j++] = pid;
3498d359177SBarry Smith #endif
3505e96ac45SJed Brown         args[j++] = 0;
351e5c89e4eSSatish Balay       }
3525e96ac45SJed Brown       if (Xterm) {
353c5888dd7SBarry 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);
354c5888dd7SBarry Smith         else            printf("PETSC: Attaching %s to %s on pid %s on %s\n",PetscDebugger,program,pid,hostname);
355a297a907SKarl Rupp 
3565e96ac45SJed Brown         if (execvp(args[0],(char**)args)  < 0) {
3575e96ac45SJed Brown           perror("Unable to start debugger in xterm");
3585e96ac45SJed Brown           exit(0);
3595e96ac45SJed Brown         }
3605e96ac45SJed Brown       } else {
361c5888dd7SBarry Smith         printf("PETSC: Attaching %s to %s of pid %s on %s\n",PetscDebugger,program,pid,hostname);
362e5c89e4eSSatish Balay         if (execvp(args[0],(char**)args)  < 0) {
363e5c89e4eSSatish Balay           perror("Unable to start debugger");
364e5c89e4eSSatish Balay           exit(0);
365e5c89e4eSSatish Balay         }
366e5c89e4eSSatish Balay       }
367e5c89e4eSSatish Balay     }
368e5c89e4eSSatish Balay   } else {   /* I am the child, continue with user code */
369e5c89e4eSSatish Balay     sleeptime = 10; /* default to sleep waiting for debugger */
370c5929fdfSBarry Smith     ierr = PetscOptionsGetReal(NULL,NULL,"-debugger_pause",&sleeptime,NULL);CHKERRQ(ierr);
371e5c89e4eSSatish Balay     if (sleeptime < 0) sleeptime = -sleeptime;
372e5c89e4eSSatish Balay #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP)
373e5c89e4eSSatish Balay     /*
374e5c89e4eSSatish Balay         HP cannot attach process to sleeping debugger, hence count instead
375e5c89e4eSSatish Balay     */
376e5c89e4eSSatish Balay     {
377e5c89e4eSSatish Balay       PetscReal x = 1.0;
378e5c89e4eSSatish Balay       int       i =10000000;
379e5c89e4eSSatish Balay       while (i--) x++;  /* cannot attach to sleeper */
380e5c89e4eSSatish Balay     }
381e5c89e4eSSatish Balay #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY)
382e5c89e4eSSatish Balay     /*
383e5c89e4eSSatish Balay         IBM sleep may return at anytime, hence must see if there is more time to sleep
384e5c89e4eSSatish Balay     */
385e5c89e4eSSatish Balay     {
386e5c89e4eSSatish Balay       int left = sleeptime;
387a297a907SKarl Rupp       while (left > 0) left = PetscSleep(left) - 1;
388e5c89e4eSSatish Balay     }
389e5c89e4eSSatish Balay #else
390e5c89e4eSSatish Balay     PetscSleep(sleeptime);
391e5c89e4eSSatish Balay #endif
392e5c89e4eSSatish Balay   }
393e5c89e4eSSatish Balay #endif
394e5c89e4eSSatish Balay   PetscFunctionReturn(0);
395e5c89e4eSSatish Balay }
396e5c89e4eSSatish Balay 
397e5c89e4eSSatish Balay /*@C
398e5c89e4eSSatish Balay    PetscAttachDebuggerErrorHandler - Error handler that attaches
399e5c89e4eSSatish Balay    a debugger to a running process when an error is detected.
400e5c89e4eSSatish Balay    This routine is useful for examining variables, etc.
401e5c89e4eSSatish Balay 
402e5c89e4eSSatish Balay    Not Collective
403e5c89e4eSSatish Balay 
404e5c89e4eSSatish Balay    Input Parameters:
405e32f2f54SBarry Smith +  comm - communicator over which error occurred
406e32f2f54SBarry Smith .  line - the line number of the error (indicated by __LINE__)
407e5c89e4eSSatish Balay .  file - the file in which the error was detected (indicated by __FILE__)
408e5c89e4eSSatish Balay .  message - an error text string, usually just printed to the screen
409e5c89e4eSSatish Balay .  number - the generic error number
410668f157eSBarry Smith .  p - PETSC_ERROR_INITIAL if error just detected, otherwise PETSC_ERROR_REPEAT
411e5c89e4eSSatish Balay -  ctx - error handler context
412e5c89e4eSSatish Balay 
413e5c89e4eSSatish Balay    Options Database Keys:
414e5c89e4eSSatish Balay .  -on_error_attach_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] - Activates
415e5c89e4eSSatish Balay    debugger attachment
416e5c89e4eSSatish Balay 
417e5c89e4eSSatish Balay    Level: developer
418e5c89e4eSSatish Balay 
419e5c89e4eSSatish Balay    Notes:
4208d359177SBarry Smith    By default the GNU debugger, gdb, is used.  Alternatives are lldb, dbx and
421e5c89e4eSSatish Balay    xxgdb,xldb (on IBM rs6000), xdb (on HP-UX).
422e5c89e4eSSatish Balay 
423e5c89e4eSSatish Balay    Most users need not directly employ this routine and the other error
424e5c89e4eSSatish Balay    handlers, but can instead use the simplified interface SETERR, which has
425e5c89e4eSSatish Balay    the calling sequence
426e32f2f54SBarry Smith $     SETERRQ(PETSC_COMM_SELF,number,p,message)
427e5c89e4eSSatish Balay 
428e5c89e4eSSatish Balay    Notes for experienced users:
429e5c89e4eSSatish Balay    Use PetscPushErrorHandler() to set the desired error handler.  The
430e5c89e4eSSatish Balay    currently available PETSc error handlers are
431e5c89e4eSSatish Balay $    PetscTraceBackErrorHandler()
432e5c89e4eSSatish Balay $    PetscAttachDebuggerErrorHandler()
433e5c89e4eSSatish Balay $    PetscAbortErrorHandler()
434e5c89e4eSSatish Balay    or you may write your own.
435e5c89e4eSSatish Balay 
436e5c89e4eSSatish Balay    Concepts: debugger^error handler
437e5c89e4eSSatish Balay    Concepts: error handler^attach debugger
438e5c89e4eSSatish Balay 
439e5c89e4eSSatish Balay .seealso:  PetscPushErrorHandler(), PetscTraceBackErrorHandler(),
440e5c89e4eSSatish Balay            PetscAbortErrorHandler()
441e5c89e4eSSatish Balay @*/
442efca3c55SSatish Balay PetscErrorCode  PetscAttachDebuggerErrorHandler(MPI_Comm comm,int line,const char *fun,const char *file,PetscErrorCode num,PetscErrorType p,const char *mess,void *ctx)
443e5c89e4eSSatish Balay {
444e5c89e4eSSatish Balay   PetscErrorCode ierr;
445e5c89e4eSSatish Balay 
446e5c89e4eSSatish Balay   PetscFunctionBegin;
447e5c89e4eSSatish Balay   if (!fun) fun = "User provided function";
448e5c89e4eSSatish Balay   if (!mess) mess = " ";
449e5c89e4eSSatish Balay 
450efca3c55SSatish Balay   (*PetscErrorPrintf)("%s() line %d in %s %s\n",fun,line,file,mess);
451e5c89e4eSSatish Balay 
452e5c89e4eSSatish Balay   ierr = PetscAttachDebugger();
453a297a907SKarl Rupp   if (ierr) abort(); /* call abort because don't want to kill other MPI processes that may successfully attach to debugger */
454e5c89e4eSSatish Balay   PetscFunctionReturn(0);
455e5c89e4eSSatish Balay }
456e5c89e4eSSatish Balay 
457e5c89e4eSSatish Balay /*@C
458e5c89e4eSSatish Balay    PetscStopForDebugger - Prints a message to the screen indicating how to
459e5c89e4eSSatish Balay          attach to the process with the debugger and then waits for the
460e5c89e4eSSatish Balay          debugger to attach.
461e5c89e4eSSatish Balay 
462e5c89e4eSSatish Balay    Not Collective
463e5c89e4eSSatish Balay 
4648d359177SBarry Smith    Level: developer
465e5c89e4eSSatish Balay 
46695452b02SPatrick Sanan    Notes:
46795452b02SPatrick Sanan     This is likely never needed since PetscAttachDebugger() is easier to use and seems to always work.
4688d359177SBarry Smith 
46995452b02SPatrick Sanan    Developer Notes:
47095452b02SPatrick Sanan     Since this can be called by the error handler, should it be calling SETERRQ() and CHKERRQ()?
471f35f84d1SBarry Smith 
472e5c89e4eSSatish Balay    Concepts: debugger^waiting for attachment
473e5c89e4eSSatish Balay 
474e5c89e4eSSatish Balay .seealso: PetscSetDebugger(), PetscAttachDebugger()
475e5c89e4eSSatish Balay @*/
4767087cfbeSBarry Smith PetscErrorCode  PetscStopForDebugger(void)
477e5c89e4eSSatish Balay {
478e5c89e4eSSatish Balay   PetscErrorCode ierr;
479e5c89e4eSSatish Balay   PetscInt       sleeptime=0;
480e5c89e4eSSatish Balay #if !defined(PETSC_CANNOT_START_DEBUGGER)
48151ec2c11SGlenn Hammond   int            ppid;
482e5c89e4eSSatish Balay   PetscMPIInt    rank;
483e5c89e4eSSatish Balay   char           program[PETSC_MAX_PATH_LEN],hostname[256];
4848d359177SBarry Smith   PetscBool      isdbx,isxldb,isxxgdb,isddd,iskdbg,isups,isxdb,islldb;
485e5c89e4eSSatish Balay #endif
486e5c89e4eSSatish Balay 
487e5c89e4eSSatish Balay   PetscFunctionBegin;
488e5c89e4eSSatish Balay #if defined(PETSC_CANNOT_START_DEBUGGER)
489e5c89e4eSSatish Balay   (*PetscErrorPrintf)("System cannot start debugger; just continuing program\n");
490e5c89e4eSSatish Balay #else
491e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
492f35f84d1SBarry Smith   if (ierr) rank = 0; /* ignore error since this may be already in error handler */
493e5c89e4eSSatish Balay   ierr = PetscGetHostName(hostname,256);
494e5c89e4eSSatish Balay   if (ierr) {
495e5c89e4eSSatish Balay     (*PetscErrorPrintf)("Cannot determine hostname; just continuing program\n");
496e5c89e4eSSatish Balay     PetscFunctionReturn(0);
497e5c89e4eSSatish Balay   }
498e5c89e4eSSatish Balay 
499e5c89e4eSSatish Balay   ierr = PetscGetProgramName(program,256);
500e5c89e4eSSatish Balay   if (ierr) {
501e5c89e4eSSatish Balay     (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n");
502e5c89e4eSSatish Balay     PetscFunctionReturn(0);
503e5c89e4eSSatish Balay   }
504e5c89e4eSSatish Balay   if (!program[0]) {
505e5c89e4eSSatish Balay     (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n");
506e5c89e4eSSatish Balay     PetscFunctionReturn(0);
507e5c89e4eSSatish Balay   }
508e5c89e4eSSatish Balay 
509e5c89e4eSSatish Balay   ppid = getpid();
510e5c89e4eSSatish Balay 
511b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"xxgdb",&isxxgdb);CHKERRQ(ierr);
512b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"ddd",&isddd);CHKERRQ(ierr);
513b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"kdbg",&iskdbg);CHKERRQ(ierr);
514b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"ups",&isups);CHKERRQ(ierr);
515b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"xldb",&isxldb);CHKERRQ(ierr);
516b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"xdb",&isxdb);CHKERRQ(ierr);
517b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"dbx",&isdbx);CHKERRQ(ierr);
518b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"lldb",&islldb);CHKERRQ(ierr);
519e5c89e4eSSatish Balay 
520c5888dd7SBarry Smith   if (isxxgdb || isups || isddd || iskdbg) printf("[%d]%s>>%s %s %d\n",rank,hostname,PetscDebugger,program,ppid);
521c5888dd7SBarry Smith   else if (isxldb) printf("[%d]%s>>%s -a %d %s\n",rank,hostname,PetscDebugger,ppid,program);
522c5888dd7SBarry Smith   else if (islldb) printf("[%d]%s>>%s -p %d\n",rank,hostname,PetscDebugger,ppid);
5238d359177SBarry Smith   else if (isdbx) {
524e5c89e4eSSatish Balay #if defined(PETSC_USE_P_FOR_DEBUGGER)
525c5888dd7SBarry Smith      printf("[%d]%s>>%s -p %d %s\n",rank,hostname,PetscDebugger,ppid,program);
526e5c89e4eSSatish Balay #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER)
527c5888dd7SBarry Smith      printf("[%d]%s>>%s -l ALL -P %d %s\n",rank,hostname,PetscDebugger,ppid,program);
528e5c89e4eSSatish Balay #elif defined(PETSC_USE_A_FOR_DEBUGGER)
529c5888dd7SBarry Smith      printf("[%d]%s>>%s -a %d\n",rank,hostname,PetscDebugger,ppid);
530e5c89e4eSSatish Balay #elif defined(PETSC_USE_PID_FOR_DEBUGGER)
531c5888dd7SBarry Smith      printf("[%d]%s>>%s -pid %d %s\n",rank,hostname,PetscDebugger,ppid,program);
532e5c89e4eSSatish Balay #else
533c5888dd7SBarry Smith      printf("[%d]%s>>%s %s %d\n",rank,hostname,PetscDebugger,program,ppid);
534e5c89e4eSSatish Balay #endif
5358d359177SBarry Smith   }
536e5c89e4eSSatish Balay #endif /* PETSC_CANNOT_START_DEBUGGER */
537e5c89e4eSSatish Balay 
538f35f84d1SBarry Smith   fflush(stdout); /* ignore error because may already be in error handler */
539e5c89e4eSSatish Balay 
540e5c89e4eSSatish Balay   sleeptime = 25; /* default to sleep waiting for debugger */
541c5929fdfSBarry Smith   PetscOptionsGetInt(NULL,NULL,"-debugger_pause",&sleeptime,NULL); /* ignore error because may already be in error handler */
542e5c89e4eSSatish Balay   if (sleeptime < 0) sleeptime = -sleeptime;
543e5c89e4eSSatish Balay #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP)
544e5c89e4eSSatish Balay   /*
545e5c89e4eSSatish Balay       HP cannot attach process to sleeping debugger, hence count instead
546e5c89e4eSSatish Balay   */
547e5c89e4eSSatish Balay   {
548e5c89e4eSSatish Balay     PetscReal x = 1.0;
549e5c89e4eSSatish Balay     int       i =10000000;
550e5c89e4eSSatish Balay     while (i--) x++;  /* cannot attach to sleeper */
551e5c89e4eSSatish Balay   }
552e5c89e4eSSatish Balay #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY)
553e5c89e4eSSatish Balay   /*
554e5c89e4eSSatish Balay       IBM sleep may return at anytime, hence must see if there is more time to sleep
555e5c89e4eSSatish Balay   */
556e5c89e4eSSatish Balay   {
557e5c89e4eSSatish Balay     int left = sleeptime;
558a297a907SKarl Rupp     while (left > 0) left = sleep(left) - 1;
559e5c89e4eSSatish Balay   }
560e5c89e4eSSatish Balay #else
561e5c89e4eSSatish Balay   PetscSleep(sleeptime);
562e5c89e4eSSatish Balay #endif
563e5c89e4eSSatish Balay   PetscFunctionReturn(0);
564e5c89e4eSSatish Balay }
565e5c89e4eSSatish Balay 
566e5c89e4eSSatish Balay 
567e5c89e4eSSatish Balay 
568