xref: /petsc/src/sys/error/adebug.c (revision bf4d2887a0c7d252f9e728fc844ebcd5378c5580)
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;
172a2a2941SBarry Smith PetscBool        petscwaitonerror = PETSC_FALSE;
18*bf4d2887SBarry Smith PetscBool        petscindebugger  = PETSC_FALSE;
19e5c89e4eSSatish Balay 
205e96ac45SJed Brown /*@C
215e96ac45SJed Brown    PetscSetDebugTerminal - Sets the terminal to use (instead of xterm) for debugging.
225e96ac45SJed Brown 
235e96ac45SJed Brown    Not Collective
245e96ac45SJed Brown 
255e96ac45SJed Brown    Input Parameters:
26a2b725a8SWilliam Gropp .  terminal - name of terminal and any flags required to execute a program.
27a5ba6984SMatthew G. Knepley               For example "xterm -e", "urxvt -e", "gnome-terminal -x".
285e96ac45SJed Brown 
295e96ac45SJed Brown    Options Database Keys:
305e96ac45SJed Brown    -debug_terminal terminal - use this terminal instead of xterm
315e96ac45SJed Brown 
325e96ac45SJed Brown    Level: developer
335e96ac45SJed Brown 
345e96ac45SJed Brown    Notes:
355e96ac45SJed Brown    You can start the debugger for all processes in the same GNU screen session.
365e96ac45SJed Brown 
37a6404fbfSBarry Smith      mpiexec -n 4 ./myapp -start_in_debugger -debug_terminal "screen -X -S debug screen"
385e96ac45SJed Brown 
395e96ac45SJed Brown    will open 4 windows in the session named "debug".
405e96ac45SJed Brown 
415e96ac45SJed Brown    Fortran Note:
425e96ac45SJed Brown    This routine is not supported in Fortran.
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;
51589a23caSBarry Smith   ierr = PetscStrncpy(DebugTerminal,terminal,sizeof(DebugTerminal));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,
62c4fb7a8fSRichard Tran Mills               usually "lldb", "dbx", "gdb", "cuda-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 .seealso: PetscAttachDebugger(), PetscAttachDebuggerErrorHandler()
76e5c89e4eSSatish Balay @*/
777087cfbeSBarry Smith PetscErrorCode  PetscSetDebugger(const char debugger[],PetscBool xterm)
78e5c89e4eSSatish Balay {
79e5c89e4eSSatish Balay   PetscErrorCode ierr;
80e5c89e4eSSatish Balay 
81e5c89e4eSSatish Balay   PetscFunctionBegin;
82e5c89e4eSSatish Balay   if (debugger) {
83589a23caSBarry Smith     ierr = PetscStrncpy(PetscDebugger,debugger,sizeof(PetscDebugger));CHKERRQ(ierr);
84e5c89e4eSSatish Balay   }
85589a23caSBarry Smith   if (Xterm) Xterm = xterm;
86e5c89e4eSSatish Balay   PetscFunctionReturn(0);
87e5c89e4eSSatish Balay }
88e5c89e4eSSatish Balay 
898d359177SBarry Smith /*@C
90f35f84d1SBarry Smith     PetscSetDefaultDebugger - Causes PETSc to use its default  debugger.
91e5c89e4eSSatish Balay 
92e5c89e4eSSatish Balay    Not collective
93e5c89e4eSSatish Balay 
948d359177SBarry Smith     Level: developer
95e5c89e4eSSatish Balay 
96e5c89e4eSSatish Balay .seealso: PetscSetDebugger(), PetscSetDebuggerFromString()
97e5c89e4eSSatish Balay @*/
987087cfbeSBarry Smith PetscErrorCode  PetscSetDefaultDebugger(void)
99e5c89e4eSSatish Balay {
100e5c89e4eSSatish Balay   PetscErrorCode ierr;
101e5c89e4eSSatish Balay 
102e5c89e4eSSatish Balay   PetscFunctionBegin;
1034211eb48SBarry Smith #if defined(PETSC_USE_DEBUGGER)
1044211eb48SBarry Smith   ierr = PetscSetDebugger(PETSC_USE_DEBUGGER,PETSC_TRUE);CHKERRQ(ierr);
105e5c89e4eSSatish Balay #endif
1065e96ac45SJed Brown   ierr = PetscSetDebugTerminal("xterm -e");CHKERRQ(ierr);
107e5c89e4eSSatish Balay   PetscFunctionReturn(0);
108e5c89e4eSSatish Balay }
109e5c89e4eSSatish Balay 
110e5c89e4eSSatish Balay static PetscErrorCode PetscCheckDebugger_Private(const char defaultDbg[], const char string[], const char *debugger[])
111e5c89e4eSSatish Balay {
112ace3abfcSBarry Smith   PetscBool      exists;
113e5c89e4eSSatish Balay   char           *f;
114e5c89e4eSSatish Balay   PetscErrorCode ierr;
115e5c89e4eSSatish Balay 
116e5c89e4eSSatish Balay   PetscFunctionBegin;
117e5c89e4eSSatish Balay   ierr = PetscStrstr(string, defaultDbg, &f);CHKERRQ(ierr);
118e5c89e4eSSatish Balay   if (f) {
119e5c89e4eSSatish Balay     ierr = PetscTestFile(string, 'x', &exists);CHKERRQ(ierr);
120a297a907SKarl Rupp     if (exists) *debugger = string;
121a297a907SKarl Rupp     else        *debugger = defaultDbg;
122e5c89e4eSSatish Balay   }
123e5c89e4eSSatish Balay   PetscFunctionReturn(0);
124e5c89e4eSSatish Balay }
125e5c89e4eSSatish Balay 
126e5c89e4eSSatish Balay /*@C
127e5c89e4eSSatish Balay     PetscSetDebuggerFromString - Set the complete path for the
128e5c89e4eSSatish Balay        debugger for PETSc to use.
129e5c89e4eSSatish Balay 
130e5c89e4eSSatish Balay    Not collective
131e5c89e4eSSatish Balay 
1327c764164SBarry Smith    Level: developer
133e5c89e4eSSatish Balay 
134e5c89e4eSSatish Balay .seealso: PetscSetDebugger(), PetscSetDefaultDebugger()
135e5c89e4eSSatish Balay @*/
1367c764164SBarry Smith PetscErrorCode  PetscSetDebuggerFromString(const char *string)
137e5c89e4eSSatish Balay {
1380298fd71SBarry Smith   const char     *debugger = NULL;
139ace3abfcSBarry Smith   PetscBool      xterm     = PETSC_TRUE;
140e5c89e4eSSatish Balay   char           *f;
141e5c89e4eSSatish Balay   PetscErrorCode ierr;
142e5c89e4eSSatish Balay 
143e5c89e4eSSatish Balay   PetscFunctionBegin;
144e5c89e4eSSatish Balay   ierr = PetscStrstr(string, "noxterm", &f);CHKERRQ(ierr);
145e5c89e4eSSatish Balay   if (f) xterm = PETSC_FALSE;
146e5c89e4eSSatish Balay   ierr = PetscStrstr(string, "ddd", &f);CHKERRQ(ierr);
147e5c89e4eSSatish Balay   if (f) xterm = PETSC_FALSE;
148e5c89e4eSSatish Balay   ierr = PetscCheckDebugger_Private("xdb",      string, &debugger);CHKERRQ(ierr);
149e5c89e4eSSatish Balay   ierr = PetscCheckDebugger_Private("dbx",      string, &debugger);CHKERRQ(ierr);
150e5c89e4eSSatish Balay   ierr = PetscCheckDebugger_Private("xldb",     string, &debugger);CHKERRQ(ierr);
151e5c89e4eSSatish Balay   ierr = PetscCheckDebugger_Private("gdb",      string, &debugger);CHKERRQ(ierr);
152c4fb7a8fSRichard Tran Mills   ierr = PetscCheckDebugger_Private("cuda-gdb", string, &debugger);CHKERRQ(ierr);
153e5c89e4eSSatish Balay   ierr = PetscCheckDebugger_Private("idb",      string, &debugger);CHKERRQ(ierr);
154e5c89e4eSSatish Balay   ierr = PetscCheckDebugger_Private("xxgdb",    string, &debugger);CHKERRQ(ierr);
155e5c89e4eSSatish Balay   ierr = PetscCheckDebugger_Private("ddd",      string, &debugger);CHKERRQ(ierr);
156bf902449SSatish Balay   ierr = PetscCheckDebugger_Private("kdbg",     string, &debugger);CHKERRQ(ierr);
157e5c89e4eSSatish Balay   ierr = PetscCheckDebugger_Private("ups",      string, &debugger);CHKERRQ(ierr);
158e5c89e4eSSatish Balay   ierr = PetscCheckDebugger_Private("workshop", string, &debugger);CHKERRQ(ierr);
159e5c89e4eSSatish Balay   ierr = PetscCheckDebugger_Private("pgdbg",    string, &debugger);CHKERRQ(ierr);
160ecbcaa78SBarry Smith   ierr = PetscCheckDebugger_Private("pathdb",   string, &debugger);CHKERRQ(ierr);
1610e9bae81SBarry Smith   ierr = PetscCheckDebugger_Private("lldb",     string, &debugger);CHKERRQ(ierr);
162e5c89e4eSSatish Balay 
163e5c89e4eSSatish Balay   ierr = PetscSetDebugger(debugger, xterm);CHKERRQ(ierr);
164e5c89e4eSSatish Balay   PetscFunctionReturn(0);
165e5c89e4eSSatish Balay }
166e5c89e4eSSatish Balay 
1672a2a2941SBarry Smith /*@
1682a2a2941SBarry Smith    PetscWaitOnError - If an error is detected and the process would normally exit the main program with MPI_Abort() sleep instead
1692a2a2941SBarry Smith                       of exiting.
1702a2a2941SBarry Smith 
1712a2a2941SBarry Smith    Not Collective
1722a2a2941SBarry Smith 
1732a2a2941SBarry Smith    Level: advanced
1742a2a2941SBarry Smith 
1752a2a2941SBarry Smith    Notes:
1762a2a2941SBarry Smith       When -start_in_debugger -debugger_ranks x,y,z is used this prevents the processes NOT listed in x,y,z from calling MPI_Abort and
1772a2a2941SBarry Smith       killing the user's debugging sessions.
1782a2a2941SBarry Smith 
1792a2a2941SBarry Smith 
1802a2a2941SBarry Smith .seealso: PetscSetDebugger(), PetscAttachDebugger()
1812a2a2941SBarry Smith @*/
1822a2a2941SBarry Smith PetscErrorCode  PetscWaitOnError()
1832a2a2941SBarry Smith {
1842a2a2941SBarry Smith   petscwaitonerror  = PETSC_TRUE;
1852a2a2941SBarry Smith   return 0;
1862a2a2941SBarry Smith }
187e5c89e4eSSatish Balay 
188e30d2299SSatish Balay /*@
189e5c89e4eSSatish Balay    PetscAttachDebugger - Attaches the debugger to the running process.
190e5c89e4eSSatish Balay 
191e5c89e4eSSatish Balay    Not Collective
192e5c89e4eSSatish Balay 
193e5c89e4eSSatish Balay    Level: advanced
194e5c89e4eSSatish Balay 
19595452b02SPatrick Sanan    Developer Notes:
19695452b02SPatrick Sanan     Since this can be called by the error handler should it be calling SETERRQ() and CHKERRQ()?
197f35f84d1SBarry Smith 
198e5c89e4eSSatish Balay .seealso: PetscSetDebugger()
199e5c89e4eSSatish Balay @*/
2007087cfbeSBarry Smith PetscErrorCode  PetscAttachDebugger(void)
201e5c89e4eSSatish Balay {
202ed50d614Sprj- #if !defined(PETSC_CANNOT_START_DEBUGGER) && defined(PETSC_HAVE_FORK)
203e5c89e4eSSatish Balay   int            child    =0;
204a6d0e24fSJed Brown   PetscReal      sleeptime=0;
205e5c89e4eSSatish Balay   PetscErrorCode ierr;
206e5c89e4eSSatish Balay   char           program[PETSC_MAX_PATH_LEN],display[256],hostname[64];
207e5c89e4eSSatish Balay #endif
208e5c89e4eSSatish Balay 
209e5c89e4eSSatish Balay   PetscFunctionBegin;
210e5c89e4eSSatish Balay #if defined(PETSC_CANNOT_START_DEBUGGER) || !defined(PETSC_HAVE_FORK)
211e5c89e4eSSatish Balay   (*PetscErrorPrintf)("System cannot start debugger\n");
212e5c89e4eSSatish Balay   (*PetscErrorPrintf)("On Cray run program in Totalview debugger\n");
213e5c89e4eSSatish Balay   (*PetscErrorPrintf)("On Windows use Developer Studio(MSDEV)\n");
21441e02c4dSJunchao Zhang   PETSCABORT(PETSC_COMM_WORLD,PETSC_ERR_SUP_SYS);
215e5c89e4eSSatish Balay #else
216589a23caSBarry Smith   ierr = PetscGetDisplay(display,sizeof(display));CHKERRQ(ierr);
217589a23caSBarry Smith   ierr = PetscGetProgramName(program,sizeof(program));CHKERRQ(ierr);
218e5c89e4eSSatish Balay   if (ierr) {
219e5c89e4eSSatish Balay     (*PetscErrorPrintf)("Cannot determine program name\n");
220e5c89e4eSSatish Balay     PetscFunctionReturn(1);
221e5c89e4eSSatish Balay   }
222e5c89e4eSSatish Balay   if (!program[0]) {
223e5c89e4eSSatish Balay     (*PetscErrorPrintf)("Cannot determine program name\n");
224e5c89e4eSSatish Balay     PetscFunctionReturn(1);
225e5c89e4eSSatish Balay   }
226e5c89e4eSSatish Balay   child = (int)fork();
227e5c89e4eSSatish Balay   if (child < 0) {
228e5c89e4eSSatish Balay     (*PetscErrorPrintf)("Error in fork() attaching debugger\n");
229e5c89e4eSSatish Balay     PetscFunctionReturn(1);
230e5c89e4eSSatish Balay   }
231*bf4d2887SBarry Smith   petscindebugger = PETSC_TRUE;
232e5c89e4eSSatish Balay 
233e5c89e4eSSatish Balay   /*
234e5c89e4eSSatish Balay       Swap role the parent and child. This is (I think) so that control c typed
235e5c89e4eSSatish Balay     in the debugger goes to the correct process.
236e5c89e4eSSatish Balay   */
237234acd79SBarry Smith #if !defined(PETSC_DO_NOT_SWAP_CHILD_FOR_DEBUGGER)
238a297a907SKarl Rupp   if (child) child = 0;
239a297a907SKarl Rupp   else       child = (int)getppid();
240234acd79SBarry Smith #endif
241e5c89e4eSSatish Balay 
242e5c89e4eSSatish Balay   if (child) { /* I am the parent, will run the debugger */
243e5c89e4eSSatish Balay     const char *args[10];
244e5c89e4eSSatish Balay     char       pid[10];
2455e96ac45SJed Brown     PetscInt   j,jj;
2460e9bae81SBarry Smith     PetscBool  isdbx,isidb,isxldb,isxxgdb,isups,isxdb,isworkshop,isddd,iskdbg,islldb;
247e5c89e4eSSatish Balay 
248589a23caSBarry Smith     ierr = PetscGetHostName(hostname,sizeof(hostname));CHKERRQ(ierr);
249e5c89e4eSSatish Balay     /*
250e5c89e4eSSatish Balay          We need to send a continue signal to the "child" process on the
251e5c89e4eSSatish Balay        alpha, otherwise it just stays off forever
252e5c89e4eSSatish Balay     */
253e5c89e4eSSatish Balay #if defined(PETSC_NEED_KILL_FOR_DEBUGGER)
254e5c89e4eSSatish Balay     kill(child,SIGCONT);
255e5c89e4eSSatish Balay #endif
256e5c89e4eSSatish Balay     sprintf(pid,"%d",child);
257e5c89e4eSSatish Balay 
258b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"xxgdb",&isxxgdb);CHKERRQ(ierr);
259b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"ddd",&isddd);CHKERRQ(ierr);
260b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"kdbg",&iskdbg);CHKERRQ(ierr);
261b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"ups",&isups);CHKERRQ(ierr);
262b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"xldb",&isxldb);CHKERRQ(ierr);
263b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"xdb",&isxdb);CHKERRQ(ierr);
264b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"dbx",&isdbx);CHKERRQ(ierr);
265b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"idb",&isidb);CHKERRQ(ierr);
266b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"workshop",&isworkshop);CHKERRQ(ierr);
267b59f628eSBarry Smith     ierr = PetscStrcmp(PetscDebugger,"lldb",&islldb);CHKERRQ(ierr);
268e5c89e4eSSatish Balay 
269e5c89e4eSSatish Balay     if (isxxgdb || isups || isddd) {
270e5c89e4eSSatish Balay       args[1] = program; args[2] = pid; args[3] = "-display";
27102c9f0b5SLisandro Dalcin       args[0] = PetscDebugger; args[4] = display; args[5] = NULL;
272c5888dd7SBarry Smith       printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname);
273e5c89e4eSSatish Balay       if (execvp(args[0],(char**)args)  < 0) {
274e5c89e4eSSatish Balay         perror("Unable to start debugger");
275e5c89e4eSSatish Balay         exit(0);
276e5c89e4eSSatish Balay       }
277bf902449SSatish Balay     } else if (iskdbg) {
278bf902449SSatish Balay       args[1] = "-p"; args[2] = pid; args[3] = program;  args[4] = "-display";
27902c9f0b5SLisandro Dalcin       args[0] = PetscDebugger; args[5] = display; args[6] = NULL;
280c5888dd7SBarry Smith       printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[3],pid,hostname);
281bf902449SSatish Balay       if (execvp(args[0],(char**)args)  < 0) {
282bf902449SSatish Balay         perror("Unable to start debugger");
283bf902449SSatish Balay         exit(0);
284bf902449SSatish Balay       }
285e5c89e4eSSatish Balay     } else if (isxldb) {
286e5c89e4eSSatish Balay       args[1] = "-a"; args[2] = pid; args[3] = program;  args[4] = "-display";
28702c9f0b5SLisandro Dalcin       args[0] = PetscDebugger; args[5] = display; args[6] = NULL;
288c5888dd7SBarry Smith       printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname);
289e5c89e4eSSatish Balay       if (execvp(args[0],(char**)args)  < 0) {
290e5c89e4eSSatish Balay         perror("Unable to start debugger");
291e5c89e4eSSatish Balay         exit(0);
292e5c89e4eSSatish Balay       }
293e5c89e4eSSatish Balay     } else if (isworkshop) {
294e5c89e4eSSatish Balay       args[1] = "-s"; args[2] = pid; args[3] = "-D"; args[4] = "-";
29502c9f0b5SLisandro Dalcin       args[0] = PetscDebugger; args[5] = pid; args[6] = "-display"; args[7] = display; args[8] = NULL;
296c5888dd7SBarry Smith       printf("PETSC: Attaching %s to %s on %s\n",args[0],pid,hostname);
297e5c89e4eSSatish Balay       if (execvp(args[0],(char**)args)  < 0) {
298e5c89e4eSSatish Balay         perror("Unable to start debugger");
299e5c89e4eSSatish Balay         exit(0);
300e5c89e4eSSatish Balay       }
3015e96ac45SJed Brown     } else {
3025e96ac45SJed Brown       j = 0;
3035e96ac45SJed Brown       if (Xterm) {
304ace3abfcSBarry Smith         PetscBool cmp;
3055e96ac45SJed Brown         char      *tmp,*tmp1;
3065e96ac45SJed Brown         ierr = PetscStrncmp(DebugTerminal,"screen",6,&cmp);CHKERRQ(ierr);
307a5ba6984SMatthew G. Knepley         if (!cmp) {ierr = PetscStrncmp(DebugTerminal,"gnome-terminal",6,&cmp);CHKERRQ(ierr);}
3085e96ac45SJed Brown         if (cmp) display[0] = 0; /* when using screen, we never pass -display */
3095e96ac45SJed Brown         args[j++] = tmp = DebugTerminal;
3105e96ac45SJed Brown         if (display[0]) {
3115e96ac45SJed Brown           args[j++] = "-display"; args[j++] = display;
3125e96ac45SJed Brown         }
3135e96ac45SJed Brown         while (*tmp) {
3145e96ac45SJed Brown           ierr = PetscStrchr(tmp,' ',&tmp1);CHKERRQ(ierr);
3155e96ac45SJed Brown           if (!tmp1) break;
3165e96ac45SJed Brown           *tmp1     = 0;
3175e96ac45SJed Brown           tmp       = tmp1+1;
3185e96ac45SJed Brown           args[j++] = tmp;
3195e96ac45SJed Brown         }
3205e96ac45SJed Brown       }
321b59f628eSBarry Smith       args[j++] = PetscDebugger;
3225e96ac45SJed Brown       jj = j;
323*bf4d2887SBarry Smith       /* this is for default gdb */
324*bf4d2887SBarry Smith       args[j++] = program;
325*bf4d2887SBarry Smith       args[j++] = pid;
326*bf4d2887SBarry Smith       args[j++] = NULL;
3275e96ac45SJed Brown 
328e5c89e4eSSatish Balay       if (isidb) {
3295e96ac45SJed Brown         j = jj;
3305e96ac45SJed Brown         args[j++] = "-pid";
3315e96ac45SJed Brown         args[j++] = pid;
3325e96ac45SJed Brown         args[j++] = "-gdb";
3335e96ac45SJed Brown         args[j++] = program;
33402c9f0b5SLisandro Dalcin         args[j++] = NULL;
335e5c89e4eSSatish Balay       }
3360e9bae81SBarry Smith       if (islldb) {
3370e9bae81SBarry Smith         j = jj;
3380e9bae81SBarry Smith         args[j++] = "-p";
3390e9bae81SBarry Smith         args[j++] = pid;
34002c9f0b5SLisandro Dalcin         args[j++] = NULL;
3410e9bae81SBarry Smith       }
342e5c89e4eSSatish Balay       if (isdbx) {
3435e96ac45SJed Brown         j = jj;
3448d359177SBarry Smith #if defined(PETSC_USE_P_FOR_DEBUGGER)
3455e96ac45SJed Brown         args[j++] = "-p";
3465e96ac45SJed Brown         args[j++] = pid;
3475e96ac45SJed Brown         args[j++] = program;
348e5c89e4eSSatish Balay #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER)
3495e96ac45SJed Brown         args[j++] = "-l";
3505e96ac45SJed Brown         args[j++] = "ALL";
3515e96ac45SJed Brown         args[j++] = "-P";
3525e96ac45SJed Brown         args[j++] = pid;
3535e96ac45SJed Brown         args[j++] = program;
354e5c89e4eSSatish Balay #elif defined(PETSC_USE_A_FOR_DEBUGGER)
3555e96ac45SJed Brown         args[j++] = "-a";
3565e96ac45SJed Brown         args[j++] = pid;
357e5c89e4eSSatish Balay #elif defined(PETSC_USE_PID_FOR_DEBUGGER)
3585e96ac45SJed Brown         args[j++] = "-pid";
3595e96ac45SJed Brown         args[j++] = pid;
3605e96ac45SJed Brown         args[j++] = program;
361493de400SSatish Balay #else
362493de400SSatish Balay         args[j++] = program;
363493de400SSatish Balay         args[j++] = pid;
3648d359177SBarry Smith #endif
36502c9f0b5SLisandro Dalcin         args[j++] = NULL;
366e5c89e4eSSatish Balay       }
3675e96ac45SJed Brown       if (Xterm) {
368c5888dd7SBarry 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);
369c5888dd7SBarry Smith         else            printf("PETSC: Attaching %s to %s on pid %s on %s\n",PetscDebugger,program,pid,hostname);
370a297a907SKarl Rupp 
3715e96ac45SJed Brown         if (execvp(args[0],(char**)args)  < 0) {
3725e96ac45SJed Brown           perror("Unable to start debugger in xterm");
3735e96ac45SJed Brown           exit(0);
3745e96ac45SJed Brown         }
3755e96ac45SJed Brown       } else {
376c5888dd7SBarry Smith         printf("PETSC: Attaching %s to %s of pid %s on %s\n",PetscDebugger,program,pid,hostname);
377e5c89e4eSSatish Balay         if (execvp(args[0],(char**)args)  < 0) {
378e5c89e4eSSatish Balay           perror("Unable to start debugger");
379e5c89e4eSSatish Balay           exit(0);
380e5c89e4eSSatish Balay         }
381e5c89e4eSSatish Balay       }
382e5c89e4eSSatish Balay     }
383e5c89e4eSSatish Balay   } else {   /* I am the child, continue with user code */
384e5c89e4eSSatish Balay     sleeptime = 10; /* default to sleep waiting for debugger */
385c5929fdfSBarry Smith     ierr = PetscOptionsGetReal(NULL,NULL,"-debugger_pause",&sleeptime,NULL);CHKERRQ(ierr);
386e5c89e4eSSatish Balay     if (sleeptime < 0) sleeptime = -sleeptime;
387e5c89e4eSSatish Balay #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP)
388e5c89e4eSSatish Balay     /*
389e5c89e4eSSatish Balay         HP cannot attach process to sleeping debugger, hence count instead
390e5c89e4eSSatish Balay     */
391e5c89e4eSSatish Balay     {
392e5c89e4eSSatish Balay       PetscReal x = 1.0;
393e5c89e4eSSatish Balay       int       i =10000000;
394e5c89e4eSSatish Balay       while (i--) x++;  /* cannot attach to sleeper */
395e5c89e4eSSatish Balay     }
396e5c89e4eSSatish Balay #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY)
397e5c89e4eSSatish Balay     /*
398e5c89e4eSSatish Balay         IBM sleep may return at anytime, hence must see if there is more time to sleep
399e5c89e4eSSatish Balay     */
400e5c89e4eSSatish Balay     {
401e5c89e4eSSatish Balay       int left = sleeptime;
402a297a907SKarl Rupp       while (left > 0) left = PetscSleep(left) - 1;
403e5c89e4eSSatish Balay     }
404e5c89e4eSSatish Balay #else
405e5c89e4eSSatish Balay     PetscSleep(sleeptime);
406e5c89e4eSSatish Balay #endif
407e5c89e4eSSatish Balay   }
408e5c89e4eSSatish Balay #endif
409e5c89e4eSSatish Balay   PetscFunctionReturn(0);
410e5c89e4eSSatish Balay }
411e5c89e4eSSatish Balay 
412e5c89e4eSSatish Balay /*@C
413e5c89e4eSSatish Balay    PetscAttachDebuggerErrorHandler - Error handler that attaches
414e5c89e4eSSatish Balay    a debugger to a running process when an error is detected.
415e5c89e4eSSatish Balay    This routine is useful for examining variables, etc.
416e5c89e4eSSatish Balay 
417e5c89e4eSSatish Balay    Not Collective
418e5c89e4eSSatish Balay 
419e5c89e4eSSatish Balay    Input Parameters:
420e32f2f54SBarry Smith +  comm - communicator over which error occurred
421e32f2f54SBarry Smith .  line - the line number of the error (indicated by __LINE__)
422e5c89e4eSSatish Balay .  file - the file in which the error was detected (indicated by __FILE__)
423e5c89e4eSSatish Balay .  message - an error text string, usually just printed to the screen
424e5c89e4eSSatish Balay .  number - the generic error number
425668f157eSBarry Smith .  p - PETSC_ERROR_INITIAL if error just detected, otherwise PETSC_ERROR_REPEAT
426e5c89e4eSSatish Balay -  ctx - error handler context
427e5c89e4eSSatish Balay 
428e5c89e4eSSatish Balay    Options Database Keys:
429e5c89e4eSSatish Balay .  -on_error_attach_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] - Activates
430e5c89e4eSSatish Balay    debugger attachment
431e5c89e4eSSatish Balay 
432e5c89e4eSSatish Balay    Level: developer
433e5c89e4eSSatish Balay 
434e5c89e4eSSatish Balay    Notes:
435c4fb7a8fSRichard Tran Mills    By default the GNU debugger, gdb, is used.  Alternatives are cuda-gdb, lldb, dbx and
436e5c89e4eSSatish Balay    xxgdb,xldb (on IBM rs6000), xdb (on HP-UX).
437e5c89e4eSSatish Balay 
438e5c89e4eSSatish Balay    Most users need not directly employ this routine and the other error
439e5c89e4eSSatish Balay    handlers, but can instead use the simplified interface SETERR, which has
440e5c89e4eSSatish Balay    the calling sequence
441e32f2f54SBarry Smith $     SETERRQ(PETSC_COMM_SELF,number,p,message)
442e5c89e4eSSatish Balay 
443e5c89e4eSSatish Balay    Notes for experienced users:
444e5c89e4eSSatish Balay    Use PetscPushErrorHandler() to set the desired error handler.  The
445e5c89e4eSSatish Balay    currently available PETSc error handlers are
446e5c89e4eSSatish Balay $    PetscTraceBackErrorHandler()
447e5c89e4eSSatish Balay $    PetscAttachDebuggerErrorHandler()
448e5c89e4eSSatish Balay $    PetscAbortErrorHandler()
449e5c89e4eSSatish Balay    or you may write your own.
450e5c89e4eSSatish Balay 
451e5c89e4eSSatish Balay 
452e5c89e4eSSatish Balay .seealso:  PetscPushErrorHandler(), PetscTraceBackErrorHandler(),
453e5c89e4eSSatish Balay            PetscAbortErrorHandler()
454e5c89e4eSSatish Balay @*/
455efca3c55SSatish Balay PetscErrorCode  PetscAttachDebuggerErrorHandler(MPI_Comm comm,int line,const char *fun,const char *file,PetscErrorCode num,PetscErrorType p,const char *mess,void *ctx)
456e5c89e4eSSatish Balay {
457e5c89e4eSSatish Balay   PetscErrorCode ierr;
458e5c89e4eSSatish Balay 
459e5c89e4eSSatish Balay   PetscFunctionBegin;
460e5c89e4eSSatish Balay   if (!fun) fun = "User provided function";
461e5c89e4eSSatish Balay   if (!mess) mess = " ";
462e5c89e4eSSatish Balay 
463efca3c55SSatish Balay   (*PetscErrorPrintf)("%s() line %d in %s %s\n",fun,line,file,mess);
464e5c89e4eSSatish Balay 
465e5c89e4eSSatish Balay   ierr = PetscAttachDebugger();
466a297a907SKarl Rupp   if (ierr) abort(); /* call abort because don't want to kill other MPI processes that may successfully attach to debugger */
467e5c89e4eSSatish Balay   PetscFunctionReturn(0);
468e5c89e4eSSatish Balay }
469e5c89e4eSSatish Balay 
470e5c89e4eSSatish Balay /*@C
471e5c89e4eSSatish Balay    PetscStopForDebugger - Prints a message to the screen indicating how to
472e5c89e4eSSatish Balay          attach to the process with the debugger and then waits for the
473e5c89e4eSSatish Balay          debugger to attach.
474e5c89e4eSSatish Balay 
475e5c89e4eSSatish Balay    Not Collective
476e5c89e4eSSatish Balay 
4778d359177SBarry Smith    Level: developer
478e5c89e4eSSatish Balay 
47995452b02SPatrick Sanan    Notes:
48095452b02SPatrick Sanan     This is likely never needed since PetscAttachDebugger() is easier to use and seems to always work.
4818d359177SBarry Smith 
48295452b02SPatrick Sanan    Developer Notes:
48395452b02SPatrick Sanan     Since this can be called by the error handler, should it be calling SETERRQ() and CHKERRQ()?
484f35f84d1SBarry Smith 
485e5c89e4eSSatish Balay .seealso: PetscSetDebugger(), PetscAttachDebugger()
486e5c89e4eSSatish Balay @*/
4877087cfbeSBarry Smith PetscErrorCode  PetscStopForDebugger(void)
488e5c89e4eSSatish Balay {
489e5c89e4eSSatish Balay   PetscErrorCode ierr;
490e5c89e4eSSatish Balay   PetscInt       sleeptime=0;
491e5c89e4eSSatish Balay #if !defined(PETSC_CANNOT_START_DEBUGGER)
49251ec2c11SGlenn Hammond   int            ppid;
493e5c89e4eSSatish Balay   PetscMPIInt    rank;
494e5c89e4eSSatish Balay   char           program[PETSC_MAX_PATH_LEN],hostname[256];
4958d359177SBarry Smith   PetscBool      isdbx,isxldb,isxxgdb,isddd,iskdbg,isups,isxdb,islldb;
496e5c89e4eSSatish Balay #endif
497e5c89e4eSSatish Balay 
498e5c89e4eSSatish Balay   PetscFunctionBegin;
499e5c89e4eSSatish Balay #if defined(PETSC_CANNOT_START_DEBUGGER)
500e5c89e4eSSatish Balay   (*PetscErrorPrintf)("System cannot start debugger; just continuing program\n");
501e5c89e4eSSatish Balay #else
502e5c89e4eSSatish Balay   ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
503f35f84d1SBarry Smith   if (ierr) rank = 0; /* ignore error since this may be already in error handler */
504589a23caSBarry Smith   ierr = PetscGetHostName(hostname,sizeof(hostname));
505e5c89e4eSSatish Balay   if (ierr) {
506e5c89e4eSSatish Balay     (*PetscErrorPrintf)("Cannot determine hostname; just continuing program\n");
507e5c89e4eSSatish Balay     PetscFunctionReturn(0);
508e5c89e4eSSatish Balay   }
509e5c89e4eSSatish Balay 
510589a23caSBarry Smith   ierr = PetscGetProgramName(program,sizeof(program));
511e5c89e4eSSatish Balay   if (ierr) {
512e5c89e4eSSatish Balay     (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n");
513e5c89e4eSSatish Balay     PetscFunctionReturn(0);
514e5c89e4eSSatish Balay   }
515e5c89e4eSSatish Balay   if (!program[0]) {
516e5c89e4eSSatish Balay     (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n");
517e5c89e4eSSatish Balay     PetscFunctionReturn(0);
518e5c89e4eSSatish Balay   }
519e5c89e4eSSatish Balay 
520e5c89e4eSSatish Balay   ppid = getpid();
521e5c89e4eSSatish Balay 
522b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"xxgdb",&isxxgdb);CHKERRQ(ierr);
523b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"ddd",&isddd);CHKERRQ(ierr);
524b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"kdbg",&iskdbg);CHKERRQ(ierr);
525b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"ups",&isups);CHKERRQ(ierr);
526b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"xldb",&isxldb);CHKERRQ(ierr);
527b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"xdb",&isxdb);CHKERRQ(ierr);
528b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"dbx",&isdbx);CHKERRQ(ierr);
529b59f628eSBarry Smith   ierr = PetscStrcmp(PetscDebugger,"lldb",&islldb);CHKERRQ(ierr);
530e5c89e4eSSatish Balay 
531c5888dd7SBarry Smith   if (isxxgdb || isups || isddd || iskdbg) printf("[%d]%s>>%s %s %d\n",rank,hostname,PetscDebugger,program,ppid);
532c5888dd7SBarry Smith   else if (isxldb) printf("[%d]%s>>%s -a %d %s\n",rank,hostname,PetscDebugger,ppid,program);
533c5888dd7SBarry Smith   else if (islldb) printf("[%d]%s>>%s -p %d\n",rank,hostname,PetscDebugger,ppid);
5348d359177SBarry Smith   else if (isdbx) {
535e5c89e4eSSatish Balay #if defined(PETSC_USE_P_FOR_DEBUGGER)
536c5888dd7SBarry Smith      printf("[%d]%s>>%s -p %d %s\n",rank,hostname,PetscDebugger,ppid,program);
537e5c89e4eSSatish Balay #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER)
538c5888dd7SBarry Smith      printf("[%d]%s>>%s -l ALL -P %d %s\n",rank,hostname,PetscDebugger,ppid,program);
539e5c89e4eSSatish Balay #elif defined(PETSC_USE_A_FOR_DEBUGGER)
540c5888dd7SBarry Smith      printf("[%d]%s>>%s -a %d\n",rank,hostname,PetscDebugger,ppid);
541e5c89e4eSSatish Balay #elif defined(PETSC_USE_PID_FOR_DEBUGGER)
542c5888dd7SBarry Smith      printf("[%d]%s>>%s -pid %d %s\n",rank,hostname,PetscDebugger,ppid,program);
543e5c89e4eSSatish Balay #else
544c5888dd7SBarry Smith      printf("[%d]%s>>%s %s %d\n",rank,hostname,PetscDebugger,program,ppid);
545e5c89e4eSSatish Balay #endif
5468d359177SBarry Smith   }
547e5c89e4eSSatish Balay #endif /* PETSC_CANNOT_START_DEBUGGER */
548e5c89e4eSSatish Balay 
549f35f84d1SBarry Smith   fflush(stdout); /* ignore error because may already be in error handler */
550e5c89e4eSSatish Balay 
551e5c89e4eSSatish Balay   sleeptime = 25; /* default to sleep waiting for debugger */
552c5929fdfSBarry Smith   PetscOptionsGetInt(NULL,NULL,"-debugger_pause",&sleeptime,NULL); /* ignore error because may already be in error handler */
553e5c89e4eSSatish Balay   if (sleeptime < 0) sleeptime = -sleeptime;
554e5c89e4eSSatish Balay #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP)
555e5c89e4eSSatish Balay   /*
556e5c89e4eSSatish Balay       HP cannot attach process to sleeping debugger, hence count instead
557e5c89e4eSSatish Balay   */
558e5c89e4eSSatish Balay   {
559e5c89e4eSSatish Balay     PetscReal x = 1.0;
560e5c89e4eSSatish Balay     int       i =10000000;
561e5c89e4eSSatish Balay     while (i--) x++;  /* cannot attach to sleeper */
562e5c89e4eSSatish Balay   }
563e5c89e4eSSatish Balay #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY)
564e5c89e4eSSatish Balay   /*
565e5c89e4eSSatish Balay       IBM sleep may return at anytime, hence must see if there is more time to sleep
566e5c89e4eSSatish Balay   */
567e5c89e4eSSatish Balay   {
568e5c89e4eSSatish Balay     int left = sleeptime;
569a297a907SKarl Rupp     while (left > 0) left = sleep(left) - 1;
570e5c89e4eSSatish Balay   }
571e5c89e4eSSatish Balay #else
572e5c89e4eSSatish Balay   PetscSleep(sleeptime);
573e5c89e4eSSatish Balay #endif
574e5c89e4eSSatish Balay   PetscFunctionReturn(0);
575e5c89e4eSSatish Balay }
576