xref: /petsc/src/sys/error/adebug.c (revision 95452b02e12c0ee11232c7ff2b24b568a8e07e43)
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.
255e96ac45SJed Brown               For example "xterm -e", "urxvt -e".
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 
186*95452b02SPatrick Sanan    Developer Notes:
187*95452b02SPatrick 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);
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 
465*95452b02SPatrick Sanan    Notes:
466*95452b02SPatrick Sanan     This is likely never needed since PetscAttachDebugger() is easier to use and seems to always work.
4678d359177SBarry Smith 
468*95452b02SPatrick Sanan    Developer Notes:
469*95452b02SPatrick Sanan     Since this can be called by the error handler, should it be calling SETERRQ() and CHKERRQ()?
470f35f84d1SBarry Smith 
471e5c89e4eSSatish Balay    Concepts: debugger^waiting for attachment
472e5c89e4eSSatish Balay 
473e5c89e4eSSatish Balay .seealso: PetscSetDebugger(), PetscAttachDebugger()
474e5c89e4eSSatish Balay @*/
4757087cfbeSBarry Smith PetscErrorCode  PetscStopForDebugger(void)
476e5c89e4eSSatish Balay {
477e5c89e4eSSatish Balay   PetscErrorCode ierr;
478e5c89e4eSSatish Balay   PetscInt       sleeptime=0;
479e5c89e4eSSatish Balay #if !defined(PETSC_CANNOT_START_DEBUGGER)
48051ec2c11SGlenn Hammond   int            ppid;
481e5c89e4eSSatish Balay   PetscMPIInt    rank;
482e5c89e4eSSatish Balay   char           program[PETSC_MAX_PATH_LEN],hostname[256];
4838d359177SBarry Smith   PetscBool      isdbx,isxldb,isxxgdb,isddd,iskdbg,isups,isxdb,islldb;
484e5c89e4eSSatish Balay #endif
485e5c89e4eSSatish Balay 
486e5c89e4eSSatish Balay   PetscFunctionBegin;
487e5c89e4eSSatish Balay #if defined(PETSC_CANNOT_START_DEBUGGER)
488e5c89e4eSSatish Balay   (*PetscErrorPrintf)("System cannot start debugger; just continuing program\n");
489e5c89e4eSSatish Balay #else
490e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
491f35f84d1SBarry Smith   if (ierr) rank = 0; /* ignore error since this may be already in error handler */
492e5c89e4eSSatish Balay   ierr = PetscGetHostName(hostname,256);
493e5c89e4eSSatish Balay   if (ierr) {
494e5c89e4eSSatish Balay     (*PetscErrorPrintf)("Cannot determine hostname; just continuing program\n");
495e5c89e4eSSatish Balay     PetscFunctionReturn(0);
496e5c89e4eSSatish Balay   }
497e5c89e4eSSatish Balay 
498e5c89e4eSSatish Balay   ierr = PetscGetProgramName(program,256);
499e5c89e4eSSatish Balay   if (ierr) {
500e5c89e4eSSatish Balay     (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n");
501e5c89e4eSSatish Balay     PetscFunctionReturn(0);
502e5c89e4eSSatish Balay   }
503e5c89e4eSSatish Balay   if (!program[0]) {
504e5c89e4eSSatish Balay     (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n");
505e5c89e4eSSatish Balay     PetscFunctionReturn(0);
506e5c89e4eSSatish Balay   }
507e5c89e4eSSatish Balay 
508e5c89e4eSSatish Balay   ppid = getpid();
509e5c89e4eSSatish Balay 
510b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"xxgdb",&isxxgdb);CHKERRQ(ierr);
511b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"ddd",&isddd);CHKERRQ(ierr);
512b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"kdbg",&iskdbg);CHKERRQ(ierr);
513b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"ups",&isups);CHKERRQ(ierr);
514b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"xldb",&isxldb);CHKERRQ(ierr);
515b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"xdb",&isxdb);CHKERRQ(ierr);
516b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"dbx",&isdbx);CHKERRQ(ierr);
517b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"lldb",&islldb);CHKERRQ(ierr);
518e5c89e4eSSatish Balay 
519c5888dd7SBarry Smith   if (isxxgdb || isups || isddd || iskdbg) printf("[%d]%s>>%s %s %d\n",rank,hostname,PetscDebugger,program,ppid);
520c5888dd7SBarry Smith   else if (isxldb) printf("[%d]%s>>%s -a %d %s\n",rank,hostname,PetscDebugger,ppid,program);
521c5888dd7SBarry Smith   else if (islldb) printf("[%d]%s>>%s -p %d\n",rank,hostname,PetscDebugger,ppid);
5228d359177SBarry Smith   else if (isdbx) {
523e5c89e4eSSatish Balay #if defined(PETSC_USE_P_FOR_DEBUGGER)
524c5888dd7SBarry Smith      printf("[%d]%s>>%s -p %d %s\n",rank,hostname,PetscDebugger,ppid,program);
525e5c89e4eSSatish Balay #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER)
526c5888dd7SBarry Smith      printf("[%d]%s>>%s -l ALL -P %d %s\n",rank,hostname,PetscDebugger,ppid,program);
527e5c89e4eSSatish Balay #elif defined(PETSC_USE_A_FOR_DEBUGGER)
528c5888dd7SBarry Smith      printf("[%d]%s>>%s -a %d\n",rank,hostname,PetscDebugger,ppid);
529e5c89e4eSSatish Balay #elif defined(PETSC_USE_PID_FOR_DEBUGGER)
530c5888dd7SBarry Smith      printf("[%d]%s>>%s -pid %d %s\n",rank,hostname,PetscDebugger,ppid,program);
531e5c89e4eSSatish Balay #else
532c5888dd7SBarry Smith      printf("[%d]%s>>%s %s %d\n",rank,hostname,PetscDebugger,program,ppid);
533e5c89e4eSSatish Balay #endif
5348d359177SBarry Smith   }
535e5c89e4eSSatish Balay #endif /* PETSC_CANNOT_START_DEBUGGER */
536e5c89e4eSSatish Balay 
537f35f84d1SBarry Smith   fflush(stdout); /* ignore error because may already be in error handler */
538e5c89e4eSSatish Balay 
539e5c89e4eSSatish Balay   sleeptime = 25; /* default to sleep waiting for debugger */
540c5929fdfSBarry Smith   PetscOptionsGetInt(NULL,NULL,"-debugger_pause",&sleeptime,NULL); /* ignore error because may already be in error handler */
541e5c89e4eSSatish Balay   if (sleeptime < 0) sleeptime = -sleeptime;
542e5c89e4eSSatish Balay #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP)
543e5c89e4eSSatish Balay   /*
544e5c89e4eSSatish Balay       HP cannot attach process to sleeping debugger, hence count instead
545e5c89e4eSSatish Balay   */
546e5c89e4eSSatish Balay   {
547e5c89e4eSSatish Balay     PetscReal x = 1.0;
548e5c89e4eSSatish Balay     int       i =10000000;
549e5c89e4eSSatish Balay     while (i--) x++;  /* cannot attach to sleeper */
550e5c89e4eSSatish Balay   }
551e5c89e4eSSatish Balay #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY)
552e5c89e4eSSatish Balay   /*
553e5c89e4eSSatish Balay       IBM sleep may return at anytime, hence must see if there is more time to sleep
554e5c89e4eSSatish Balay   */
555e5c89e4eSSatish Balay   {
556e5c89e4eSSatish Balay     int left = sleeptime;
557a297a907SKarl Rupp     while (left > 0) left = sleep(left) - 1;
558e5c89e4eSSatish Balay   }
559e5c89e4eSSatish Balay #else
560e5c89e4eSSatish Balay   PetscSleep(sleeptime);
561e5c89e4eSSatish Balay #endif
562e5c89e4eSSatish Balay   PetscFunctionReturn(0);
563e5c89e4eSSatish Balay }
564e5c89e4eSSatish Balay 
565e5c89e4eSSatish Balay 
566e5c89e4eSSatish Balay 
567