xref: /petsc/src/sys/error/adebug.c (revision a5ba69842134ac4a332e52b083152191e028dc76)
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:
245e96ac45SJed Brown +  terminal - name of terminal and any flags required to execute a program.
25*a5ba6984SMatthew 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 
186f35f84d1SBarry Smith    Developer Notes: Since this can be called by the error handler should it be calling SETERRQ() and CHKERRQ()?
187f35f84d1SBarry Smith 
188e5c89e4eSSatish Balay .seealso: PetscSetDebugger()
189e5c89e4eSSatish Balay @*/
1907087cfbeSBarry Smith PetscErrorCode  PetscAttachDebugger(void)
191e5c89e4eSSatish Balay {
192e5c89e4eSSatish Balay #if !defined(PETSC_CANNOT_START_DEBUGGER)
193e5c89e4eSSatish Balay   int            child    =0;
194a6d0e24fSJed Brown   PetscReal      sleeptime=0;
195e5c89e4eSSatish Balay   PetscErrorCode ierr;
196e5c89e4eSSatish Balay   char           program[PETSC_MAX_PATH_LEN],display[256],hostname[64];
197e5c89e4eSSatish Balay #endif
198e5c89e4eSSatish Balay 
199e5c89e4eSSatish Balay   PetscFunctionBegin;
200e5c89e4eSSatish Balay #if defined(PETSC_CANNOT_START_DEBUGGER) || !defined(PETSC_HAVE_FORK)
201e5c89e4eSSatish Balay   (*PetscErrorPrintf)("System cannot start debugger\n");
202e5c89e4eSSatish Balay   (*PetscErrorPrintf)("On Cray run program in Totalview debugger\n");
203e5c89e4eSSatish Balay   (*PetscErrorPrintf)("On Windows use Developer Studio(MSDEV)\n");
204fa6b8e38SSatish Balay   MPI_Abort(PETSC_COMM_WORLD,1);
205e5c89e4eSSatish Balay #else
206e5c89e4eSSatish Balay   ierr = PetscGetDisplay(display,128);CHKERRQ(ierr);
207e5c89e4eSSatish Balay   ierr = PetscGetProgramName(program,PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
208e5c89e4eSSatish Balay   if (ierr) {
209e5c89e4eSSatish Balay     (*PetscErrorPrintf)("Cannot determine program name\n");
210e5c89e4eSSatish Balay     PetscFunctionReturn(1);
211e5c89e4eSSatish Balay   }
212e5c89e4eSSatish Balay   if (!program[0]) {
213e5c89e4eSSatish Balay     (*PetscErrorPrintf)("Cannot determine program name\n");
214e5c89e4eSSatish Balay     PetscFunctionReturn(1);
215e5c89e4eSSatish Balay   }
216e5c89e4eSSatish Balay   child = (int)fork();
217e5c89e4eSSatish Balay   if (child < 0) {
218e5c89e4eSSatish Balay     (*PetscErrorPrintf)("Error in fork() attaching debugger\n");
219e5c89e4eSSatish Balay     PetscFunctionReturn(1);
220e5c89e4eSSatish Balay   }
221e5c89e4eSSatish Balay 
222e5c89e4eSSatish Balay   /*
223e5c89e4eSSatish Balay       Swap role the parent and child. This is (I think) so that control c typed
224e5c89e4eSSatish Balay     in the debugger goes to the correct process.
225e5c89e4eSSatish Balay   */
226a297a907SKarl Rupp   if (child) child = 0;
227a297a907SKarl Rupp   else       child = (int)getppid();
228e5c89e4eSSatish Balay 
229e5c89e4eSSatish Balay   if (child) { /* I am the parent, will run the debugger */
230e5c89e4eSSatish Balay     const char *args[10];
231e5c89e4eSSatish Balay     char       pid[10];
2325e96ac45SJed Brown     PetscInt   j,jj;
2330e9bae81SBarry Smith     PetscBool  isdbx,isidb,isxldb,isxxgdb,isups,isxdb,isworkshop,isddd,iskdbg,islldb;
234e5c89e4eSSatish Balay 
235e5c89e4eSSatish Balay     ierr = PetscGetHostName(hostname,64);CHKERRQ(ierr);
236e5c89e4eSSatish Balay     /*
237e5c89e4eSSatish Balay          We need to send a continue signal to the "child" process on the
238e5c89e4eSSatish Balay        alpha, otherwise it just stays off forever
239e5c89e4eSSatish Balay     */
240e5c89e4eSSatish Balay #if defined(PETSC_NEED_KILL_FOR_DEBUGGER)
241e5c89e4eSSatish Balay     kill(child,SIGCONT);
242e5c89e4eSSatish Balay #endif
243e5c89e4eSSatish Balay     sprintf(pid,"%d",child);
244e5c89e4eSSatish Balay 
245b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"xxgdb",&isxxgdb);CHKERRQ(ierr);
246b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"ddd",&isddd);CHKERRQ(ierr);
247b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"kdbg",&iskdbg);CHKERRQ(ierr);
248b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"ups",&isups);CHKERRQ(ierr);
249b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"xldb",&isxldb);CHKERRQ(ierr);
250b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"xdb",&isxdb);CHKERRQ(ierr);
251b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"dbx",&isdbx);CHKERRQ(ierr);
252b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"idb",&isidb);CHKERRQ(ierr);
253b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"workshop",&isworkshop);CHKERRQ(ierr);
254b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"lldb",&islldb);CHKERRQ(ierr);
255e5c89e4eSSatish Balay 
256e5c89e4eSSatish Balay     if (isxxgdb || isups || isddd) {
257e5c89e4eSSatish Balay       args[1] = program; args[2] = pid; args[3] = "-display";
258b59f628eSBarry Smith       args[0] = PetscDebugger; args[4] = display; args[5] = 0;
259c5888dd7SBarry Smith       printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname);
260e5c89e4eSSatish Balay       if (execvp(args[0],(char**)args)  < 0) {
261e5c89e4eSSatish Balay         perror("Unable to start debugger");
262e5c89e4eSSatish Balay         exit(0);
263e5c89e4eSSatish Balay       }
264bf902449SSatish Balay     } else if (iskdbg) {
265bf902449SSatish Balay       args[1] = "-p"; args[2] = pid; args[3] = program;  args[4] = "-display";
266b59f628eSBarry Smith       args[0] = PetscDebugger; args[5] = display; args[6] = 0;
267c5888dd7SBarry Smith       printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[3],pid,hostname);
268bf902449SSatish Balay       if (execvp(args[0],(char**)args)  < 0) {
269bf902449SSatish Balay         perror("Unable to start debugger");
270bf902449SSatish Balay         exit(0);
271bf902449SSatish Balay       }
272e5c89e4eSSatish Balay     } else if (isxldb) {
273e5c89e4eSSatish Balay       args[1] = "-a"; args[2] = pid; args[3] = program;  args[4] = "-display";
274b59f628eSBarry Smith       args[0] = PetscDebugger; args[5] = display; args[6] = 0;
275c5888dd7SBarry Smith       printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname);
276e5c89e4eSSatish Balay       if (execvp(args[0],(char**)args)  < 0) {
277e5c89e4eSSatish Balay         perror("Unable to start debugger");
278e5c89e4eSSatish Balay         exit(0);
279e5c89e4eSSatish Balay       }
280e5c89e4eSSatish Balay     } else if (isworkshop) {
281e5c89e4eSSatish Balay       args[1] = "-s"; args[2] = pid; args[3] = "-D"; args[4] = "-";
282b59f628eSBarry Smith       args[0] = PetscDebugger; args[5] = pid; args[6] = "-display"; args[7] = display; args[8] = 0;
283c5888dd7SBarry Smith       printf("PETSC: Attaching %s to %s on %s\n",args[0],pid,hostname);
284e5c89e4eSSatish Balay       if (execvp(args[0],(char**)args)  < 0) {
285e5c89e4eSSatish Balay         perror("Unable to start debugger");
286e5c89e4eSSatish Balay         exit(0);
287e5c89e4eSSatish Balay       }
2885e96ac45SJed Brown     } else {
2895e96ac45SJed Brown       j = 0;
2905e96ac45SJed Brown       if (Xterm) {
291ace3abfcSBarry Smith         PetscBool cmp;
2925e96ac45SJed Brown         char      *tmp,*tmp1;
2935e96ac45SJed Brown         ierr = PetscStrncmp(DebugTerminal,"screen",6,&cmp);CHKERRQ(ierr);
294*a5ba6984SMatthew G. Knepley         if (!cmp) {ierr = PetscStrncmp(DebugTerminal,"gnome-terminal",6,&cmp);CHKERRQ(ierr);}
2955e96ac45SJed Brown         if (cmp) display[0] = 0; /* when using screen, we never pass -display */
2965e96ac45SJed Brown         args[j++] = tmp = DebugTerminal;
2975e96ac45SJed Brown         if (display[0]) {
2985e96ac45SJed Brown           args[j++] = "-display"; args[j++] = display;
2995e96ac45SJed Brown         }
3005e96ac45SJed Brown         while (*tmp) {
3015e96ac45SJed Brown           ierr = PetscStrchr(tmp,' ',&tmp1);CHKERRQ(ierr);
3025e96ac45SJed Brown           if (!tmp1) break;
3035e96ac45SJed Brown           *tmp1     = 0;
3045e96ac45SJed Brown           tmp       = tmp1+1;
3055e96ac45SJed Brown           args[j++] = tmp;
3065e96ac45SJed Brown         }
3075e96ac45SJed Brown       }
308b59f628eSBarry Smith       args[j++] = PetscDebugger;
3095e96ac45SJed Brown       jj = j;
3105e96ac45SJed Brown       args[j++] = program; args[j++] = pid; args[j++] = 0;
3115e96ac45SJed Brown 
312e5c89e4eSSatish Balay       if (isidb) {
3135e96ac45SJed Brown         j = jj;
3145e96ac45SJed Brown         args[j++] = "-pid";
3155e96ac45SJed Brown         args[j++] = pid;
3165e96ac45SJed Brown         args[j++] = "-gdb";
3175e96ac45SJed Brown         args[j++] = program;
3185e96ac45SJed Brown         args[j++] = 0;
319e5c89e4eSSatish Balay       }
3200e9bae81SBarry Smith       if (islldb) {
3210e9bae81SBarry Smith         j = jj;
3220e9bae81SBarry Smith         args[j++] = "-p";
3230e9bae81SBarry Smith         args[j++] = pid;
3240e9bae81SBarry Smith         args[j++] = 0;
3250e9bae81SBarry Smith       }
326e5c89e4eSSatish Balay       if (isdbx) {
3275e96ac45SJed Brown         j = jj;
3288d359177SBarry Smith #if defined(PETSC_USE_P_FOR_DEBUGGER)
3295e96ac45SJed Brown         args[j++] = "-p";
3305e96ac45SJed Brown         args[j++] = pid;
3315e96ac45SJed Brown         args[j++] = program;
332e5c89e4eSSatish Balay #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER)
3335e96ac45SJed Brown         args[j++] = "-l";
3345e96ac45SJed Brown         args[j++] = "ALL";
3355e96ac45SJed Brown         args[j++] = "-P";
3365e96ac45SJed Brown         args[j++] = pid;
3375e96ac45SJed Brown         args[j++] = program;
338e5c89e4eSSatish Balay #elif defined(PETSC_USE_A_FOR_DEBUGGER)
3395e96ac45SJed Brown         args[j++] = "-a";
3405e96ac45SJed Brown         args[j++] = pid;
341e5c89e4eSSatish Balay #elif defined(PETSC_USE_PID_FOR_DEBUGGER)
3425e96ac45SJed Brown         args[j++] = "-pid";
3435e96ac45SJed Brown         args[j++] = pid;
3445e96ac45SJed Brown         args[j++] = program;
345493de400SSatish Balay #else
346493de400SSatish Balay         args[j++] = program;
347493de400SSatish Balay         args[j++] = pid;
3488d359177SBarry Smith #endif
3495e96ac45SJed Brown         args[j++] = 0;
350e5c89e4eSSatish Balay       }
3515e96ac45SJed Brown       if (Xterm) {
352c5888dd7SBarry 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);
353c5888dd7SBarry Smith         else            printf("PETSC: Attaching %s to %s on pid %s on %s\n",PetscDebugger,program,pid,hostname);
354a297a907SKarl Rupp 
3555e96ac45SJed Brown         if (execvp(args[0],(char**)args)  < 0) {
3565e96ac45SJed Brown           perror("Unable to start debugger in xterm");
3575e96ac45SJed Brown           exit(0);
3585e96ac45SJed Brown         }
3595e96ac45SJed Brown       } else {
360c5888dd7SBarry Smith         printf("PETSC: Attaching %s to %s of pid %s on %s\n",PetscDebugger,program,pid,hostname);
361e5c89e4eSSatish Balay         if (execvp(args[0],(char**)args)  < 0) {
362e5c89e4eSSatish Balay           perror("Unable to start debugger");
363e5c89e4eSSatish Balay           exit(0);
364e5c89e4eSSatish Balay         }
365e5c89e4eSSatish Balay       }
366e5c89e4eSSatish Balay     }
367e5c89e4eSSatish Balay   } else {   /* I am the child, continue with user code */
368e5c89e4eSSatish Balay     sleeptime = 10; /* default to sleep waiting for debugger */
369c5929fdfSBarry Smith     ierr = PetscOptionsGetReal(NULL,NULL,"-debugger_pause",&sleeptime,NULL);CHKERRQ(ierr);
370e5c89e4eSSatish Balay     if (sleeptime < 0) sleeptime = -sleeptime;
371e5c89e4eSSatish Balay #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP)
372e5c89e4eSSatish Balay     /*
373e5c89e4eSSatish Balay         HP cannot attach process to sleeping debugger, hence count instead
374e5c89e4eSSatish Balay     */
375e5c89e4eSSatish Balay     {
376e5c89e4eSSatish Balay       PetscReal x = 1.0;
377e5c89e4eSSatish Balay       int       i =10000000;
378e5c89e4eSSatish Balay       while (i--) x++;  /* cannot attach to sleeper */
379e5c89e4eSSatish Balay     }
380e5c89e4eSSatish Balay #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY)
381e5c89e4eSSatish Balay     /*
382e5c89e4eSSatish Balay         IBM sleep may return at anytime, hence must see if there is more time to sleep
383e5c89e4eSSatish Balay     */
384e5c89e4eSSatish Balay     {
385e5c89e4eSSatish Balay       int left = sleeptime;
386a297a907SKarl Rupp       while (left > 0) left = PetscSleep(left) - 1;
387e5c89e4eSSatish Balay     }
388e5c89e4eSSatish Balay #else
389e5c89e4eSSatish Balay     PetscSleep(sleeptime);
390e5c89e4eSSatish Balay #endif
391e5c89e4eSSatish Balay   }
392e5c89e4eSSatish Balay #endif
393e5c89e4eSSatish Balay   PetscFunctionReturn(0);
394e5c89e4eSSatish Balay }
395e5c89e4eSSatish Balay 
396e5c89e4eSSatish Balay /*@C
397e5c89e4eSSatish Balay    PetscAttachDebuggerErrorHandler - Error handler that attaches
398e5c89e4eSSatish Balay    a debugger to a running process when an error is detected.
399e5c89e4eSSatish Balay    This routine is useful for examining variables, etc.
400e5c89e4eSSatish Balay 
401e5c89e4eSSatish Balay    Not Collective
402e5c89e4eSSatish Balay 
403e5c89e4eSSatish Balay    Input Parameters:
404e32f2f54SBarry Smith +  comm - communicator over which error occurred
405e32f2f54SBarry Smith .  line - the line number of the error (indicated by __LINE__)
406e5c89e4eSSatish Balay .  file - the file in which the error was detected (indicated by __FILE__)
407e5c89e4eSSatish Balay .  message - an error text string, usually just printed to the screen
408e5c89e4eSSatish Balay .  number - the generic error number
409668f157eSBarry Smith .  p - PETSC_ERROR_INITIAL if error just detected, otherwise PETSC_ERROR_REPEAT
410e5c89e4eSSatish Balay -  ctx - error handler context
411e5c89e4eSSatish Balay 
412e5c89e4eSSatish Balay    Options Database Keys:
413e5c89e4eSSatish Balay .  -on_error_attach_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] - Activates
414e5c89e4eSSatish Balay    debugger attachment
415e5c89e4eSSatish Balay 
416e5c89e4eSSatish Balay    Level: developer
417e5c89e4eSSatish Balay 
418e5c89e4eSSatish Balay    Notes:
4198d359177SBarry Smith    By default the GNU debugger, gdb, is used.  Alternatives are lldb, dbx and
420e5c89e4eSSatish Balay    xxgdb,xldb (on IBM rs6000), xdb (on HP-UX).
421e5c89e4eSSatish Balay 
422e5c89e4eSSatish Balay    Most users need not directly employ this routine and the other error
423e5c89e4eSSatish Balay    handlers, but can instead use the simplified interface SETERR, which has
424e5c89e4eSSatish Balay    the calling sequence
425e32f2f54SBarry Smith $     SETERRQ(PETSC_COMM_SELF,number,p,message)
426e5c89e4eSSatish Balay 
427e5c89e4eSSatish Balay    Notes for experienced users:
428e5c89e4eSSatish Balay    Use PetscPushErrorHandler() to set the desired error handler.  The
429e5c89e4eSSatish Balay    currently available PETSc error handlers are
430e5c89e4eSSatish Balay $    PetscTraceBackErrorHandler()
431e5c89e4eSSatish Balay $    PetscAttachDebuggerErrorHandler()
432e5c89e4eSSatish Balay $    PetscAbortErrorHandler()
433e5c89e4eSSatish Balay    or you may write your own.
434e5c89e4eSSatish Balay 
435e5c89e4eSSatish Balay    Concepts: debugger^error handler
436e5c89e4eSSatish Balay    Concepts: error handler^attach debugger
437e5c89e4eSSatish Balay 
438e5c89e4eSSatish Balay .seealso:  PetscPushErrorHandler(), PetscTraceBackErrorHandler(),
439e5c89e4eSSatish Balay            PetscAbortErrorHandler()
440e5c89e4eSSatish Balay @*/
441efca3c55SSatish Balay PetscErrorCode  PetscAttachDebuggerErrorHandler(MPI_Comm comm,int line,const char *fun,const char *file,PetscErrorCode num,PetscErrorType p,const char *mess,void *ctx)
442e5c89e4eSSatish Balay {
443e5c89e4eSSatish Balay   PetscErrorCode ierr;
444e5c89e4eSSatish Balay 
445e5c89e4eSSatish Balay   PetscFunctionBegin;
446e5c89e4eSSatish Balay   if (!fun) fun = "User provided function";
447e5c89e4eSSatish Balay   if (!mess) mess = " ";
448e5c89e4eSSatish Balay 
449efca3c55SSatish Balay   (*PetscErrorPrintf)("%s() line %d in %s %s\n",fun,line,file,mess);
450e5c89e4eSSatish Balay 
451e5c89e4eSSatish Balay   ierr = PetscAttachDebugger();
452a297a907SKarl Rupp   if (ierr) abort(); /* call abort because don't want to kill other MPI processes that may successfully attach to debugger */
453e5c89e4eSSatish Balay   PetscFunctionReturn(0);
454e5c89e4eSSatish Balay }
455e5c89e4eSSatish Balay 
456e5c89e4eSSatish Balay /*@C
457e5c89e4eSSatish Balay    PetscStopForDebugger - Prints a message to the screen indicating how to
458e5c89e4eSSatish Balay          attach to the process with the debugger and then waits for the
459e5c89e4eSSatish Balay          debugger to attach.
460e5c89e4eSSatish Balay 
461e5c89e4eSSatish Balay    Not Collective
462e5c89e4eSSatish Balay 
4638d359177SBarry Smith    Level: developer
464e5c89e4eSSatish Balay 
4658d359177SBarry Smith    Notes: This is likely never needed since PetscAttachDebugger() is easier to use and seems to always work.
4668d359177SBarry Smith 
4678d359177SBarry Smith    Developer Notes: Since this can be called by the error handler, should it be calling SETERRQ() and CHKERRQ()?
468f35f84d1SBarry Smith 
469e5c89e4eSSatish Balay    Concepts: debugger^waiting for attachment
470e5c89e4eSSatish Balay 
471e5c89e4eSSatish Balay .seealso: PetscSetDebugger(), PetscAttachDebugger()
472e5c89e4eSSatish Balay @*/
4737087cfbeSBarry Smith PetscErrorCode  PetscStopForDebugger(void)
474e5c89e4eSSatish Balay {
475e5c89e4eSSatish Balay   PetscErrorCode ierr;
476e5c89e4eSSatish Balay   PetscInt       sleeptime=0;
477e5c89e4eSSatish Balay #if !defined(PETSC_CANNOT_START_DEBUGGER)
47851ec2c11SGlenn Hammond   int            ppid;
479e5c89e4eSSatish Balay   PetscMPIInt    rank;
480e5c89e4eSSatish Balay   char           program[PETSC_MAX_PATH_LEN],hostname[256];
4818d359177SBarry Smith   PetscBool      isdbx,isxldb,isxxgdb,isddd,iskdbg,isups,isxdb,islldb;
482e5c89e4eSSatish Balay #endif
483e5c89e4eSSatish Balay 
484e5c89e4eSSatish Balay   PetscFunctionBegin;
485e5c89e4eSSatish Balay #if defined(PETSC_CANNOT_START_DEBUGGER)
486e5c89e4eSSatish Balay   (*PetscErrorPrintf)("System cannot start debugger; just continuing program\n");
487e5c89e4eSSatish Balay #else
488e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
489f35f84d1SBarry Smith   if (ierr) rank = 0; /* ignore error since this may be already in error handler */
490e5c89e4eSSatish Balay   ierr = PetscGetHostName(hostname,256);
491e5c89e4eSSatish Balay   if (ierr) {
492e5c89e4eSSatish Balay     (*PetscErrorPrintf)("Cannot determine hostname; just continuing program\n");
493e5c89e4eSSatish Balay     PetscFunctionReturn(0);
494e5c89e4eSSatish Balay   }
495e5c89e4eSSatish Balay 
496e5c89e4eSSatish Balay   ierr = PetscGetProgramName(program,256);
497e5c89e4eSSatish Balay   if (ierr) {
498e5c89e4eSSatish Balay     (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n");
499e5c89e4eSSatish Balay     PetscFunctionReturn(0);
500e5c89e4eSSatish Balay   }
501e5c89e4eSSatish Balay   if (!program[0]) {
502e5c89e4eSSatish Balay     (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n");
503e5c89e4eSSatish Balay     PetscFunctionReturn(0);
504e5c89e4eSSatish Balay   }
505e5c89e4eSSatish Balay 
506e5c89e4eSSatish Balay   ppid = getpid();
507e5c89e4eSSatish Balay 
508b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"xxgdb",&isxxgdb);CHKERRQ(ierr);
509b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"ddd",&isddd);CHKERRQ(ierr);
510b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"kdbg",&iskdbg);CHKERRQ(ierr);
511b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"ups",&isups);CHKERRQ(ierr);
512b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"xldb",&isxldb);CHKERRQ(ierr);
513b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"xdb",&isxdb);CHKERRQ(ierr);
514b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"dbx",&isdbx);CHKERRQ(ierr);
515b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"lldb",&islldb);CHKERRQ(ierr);
516e5c89e4eSSatish Balay 
517c5888dd7SBarry Smith   if (isxxgdb || isups || isddd || iskdbg) printf("[%d]%s>>%s %s %d\n",rank,hostname,PetscDebugger,program,ppid);
518c5888dd7SBarry Smith   else if (isxldb) printf("[%d]%s>>%s -a %d %s\n",rank,hostname,PetscDebugger,ppid,program);
519c5888dd7SBarry Smith   else if (islldb) printf("[%d]%s>>%s -p %d\n",rank,hostname,PetscDebugger,ppid);
5208d359177SBarry Smith   else if (isdbx) {
521e5c89e4eSSatish Balay #if defined(PETSC_USE_P_FOR_DEBUGGER)
522c5888dd7SBarry Smith      printf("[%d]%s>>%s -p %d %s\n",rank,hostname,PetscDebugger,ppid,program);
523e5c89e4eSSatish Balay #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER)
524c5888dd7SBarry Smith      printf("[%d]%s>>%s -l ALL -P %d %s\n",rank,hostname,PetscDebugger,ppid,program);
525e5c89e4eSSatish Balay #elif defined(PETSC_USE_A_FOR_DEBUGGER)
526c5888dd7SBarry Smith      printf("[%d]%s>>%s -a %d\n",rank,hostname,PetscDebugger,ppid);
527e5c89e4eSSatish Balay #elif defined(PETSC_USE_PID_FOR_DEBUGGER)
528c5888dd7SBarry Smith      printf("[%d]%s>>%s -pid %d %s\n",rank,hostname,PetscDebugger,ppid,program);
529e5c89e4eSSatish Balay #else
530c5888dd7SBarry Smith      printf("[%d]%s>>%s %s %d\n",rank,hostname,PetscDebugger,program,ppid);
531e5c89e4eSSatish Balay #endif
5328d359177SBarry Smith   }
533e5c89e4eSSatish Balay #endif /* PETSC_CANNOT_START_DEBUGGER */
534e5c89e4eSSatish Balay 
535f35f84d1SBarry Smith   fflush(stdout); /* ignore error because may already be in error handler */
536e5c89e4eSSatish Balay 
537e5c89e4eSSatish Balay   sleeptime = 25; /* default to sleep waiting for debugger */
538c5929fdfSBarry Smith   PetscOptionsGetInt(NULL,NULL,"-debugger_pause",&sleeptime,NULL); /* ignore error because may already be in error handler */
539e5c89e4eSSatish Balay   if (sleeptime < 0) sleeptime = -sleeptime;
540e5c89e4eSSatish Balay #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP)
541e5c89e4eSSatish Balay   /*
542e5c89e4eSSatish Balay       HP cannot attach process to sleeping debugger, hence count instead
543e5c89e4eSSatish Balay   */
544e5c89e4eSSatish Balay   {
545e5c89e4eSSatish Balay     PetscReal x = 1.0;
546e5c89e4eSSatish Balay     int       i =10000000;
547e5c89e4eSSatish Balay     while (i--) x++;  /* cannot attach to sleeper */
548e5c89e4eSSatish Balay   }
549e5c89e4eSSatish Balay #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY)
550e5c89e4eSSatish Balay   /*
551e5c89e4eSSatish Balay       IBM sleep may return at anytime, hence must see if there is more time to sleep
552e5c89e4eSSatish Balay   */
553e5c89e4eSSatish Balay   {
554e5c89e4eSSatish Balay     int left = sleeptime;
555a297a907SKarl Rupp     while (left > 0) left = sleep(left) - 1;
556e5c89e4eSSatish Balay   }
557e5c89e4eSSatish Balay #else
558e5c89e4eSSatish Balay   PetscSleep(sleeptime);
559e5c89e4eSSatish Balay #endif
560e5c89e4eSSatish Balay   PetscFunctionReturn(0);
561e5c89e4eSSatish Balay }
562e5c89e4eSSatish Balay 
563e5c89e4eSSatish Balay 
564e5c89e4eSSatish Balay 
565