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. 25a5ba6984SMatthew G. Knepley For example "xterm -e", "urxvt -e", "gnome-terminal -x". 265e96ac45SJed Brown 275e96ac45SJed Brown Options Database Keys: 285e96ac45SJed Brown -debug_terminal terminal - use this terminal instead of xterm 295e96ac45SJed Brown 305e96ac45SJed Brown Level: developer 315e96ac45SJed Brown 325e96ac45SJed Brown Notes: 335e96ac45SJed Brown You can start the debugger for all processes in the same GNU screen session. 345e96ac45SJed Brown 35a6404fbfSBarry Smith mpiexec -n 4 ./myapp -start_in_debugger -debug_terminal "screen -X -S debug screen" 365e96ac45SJed Brown 375e96ac45SJed Brown will open 4 windows in the session named "debug". 385e96ac45SJed Brown 395e96ac45SJed Brown Fortran Note: 405e96ac45SJed Brown This routine is not supported in Fortran. 415e96ac45SJed Brown 425e96ac45SJed Brown .seealso: PetscSetDebugger() 435e96ac45SJed Brown @*/ 447087cfbeSBarry Smith PetscErrorCode PetscSetDebugTerminal(const char terminal[]) 455e96ac45SJed Brown { 465e96ac45SJed Brown PetscErrorCode ierr; 475e96ac45SJed Brown 485e96ac45SJed Brown PetscFunctionBegin; 495e96ac45SJed Brown ierr = PetscStrcpy(DebugTerminal,terminal);CHKERRQ(ierr); 505e96ac45SJed Brown PetscFunctionReturn(0); 515e96ac45SJed Brown } 525e96ac45SJed Brown 53e5c89e4eSSatish Balay /*@C 54e5c89e4eSSatish Balay PetscSetDebugger - Sets options associated with the debugger. 55e5c89e4eSSatish Balay 56e5c89e4eSSatish Balay Not Collective 57e5c89e4eSSatish Balay 58e5c89e4eSSatish Balay Input Parameters: 59e5c89e4eSSatish Balay + debugger - name of debugger, which should be in your path, 608d359177SBarry Smith usually "lldb", "dbx", "gdb", "idb", "xxgdb", "kdgb" or "ddd". Also, HP-UX 61e5c89e4eSSatish Balay supports "xdb", and IBM rs6000 supports "xldb". 62e5c89e4eSSatish Balay 638d359177SBarry Smith - xterm - flag to indicate debugger window, set to either PETSC_TRUE (to indicate 648d359177SBarry Smith debugger should be started in a new xterm) or PETSC_FALSE (to start debugger 658d359177SBarry Smith in initial window (the option PETSC_FALSE makes no sense when using more 668d359177SBarry Smith than one MPI process.) 67e5c89e4eSSatish Balay 68e5c89e4eSSatish Balay Level: developer 69e5c89e4eSSatish Balay 70e5c89e4eSSatish Balay Fortran Note: 71e5c89e4eSSatish Balay This routine is not supported in Fortran. 72e5c89e4eSSatish Balay 73e5c89e4eSSatish Balay .seealso: PetscAttachDebugger(), PetscAttachDebuggerErrorHandler() 74e5c89e4eSSatish Balay @*/ 757087cfbeSBarry Smith PetscErrorCode PetscSetDebugger(const char debugger[],PetscBool xterm) 76e5c89e4eSSatish Balay { 77e5c89e4eSSatish Balay PetscErrorCode ierr; 78e5c89e4eSSatish Balay 79e5c89e4eSSatish Balay PetscFunctionBegin; 80e5c89e4eSSatish Balay if (debugger) { 81b59f628eSBarry Smith ierr = PetscStrcpy(PetscDebugger,debugger);CHKERRQ(ierr); 82e5c89e4eSSatish Balay } 83e5c89e4eSSatish Balay Xterm = xterm; 84e5c89e4eSSatish Balay PetscFunctionReturn(0); 85e5c89e4eSSatish Balay } 86e5c89e4eSSatish Balay 878d359177SBarry Smith /*@C 88f35f84d1SBarry Smith PetscSetDefaultDebugger - Causes PETSc to use its default debugger. 89e5c89e4eSSatish Balay 90e5c89e4eSSatish Balay Not collective 91e5c89e4eSSatish Balay 928d359177SBarry Smith Level: developer 93e5c89e4eSSatish Balay 94e5c89e4eSSatish Balay .seealso: PetscSetDebugger(), PetscSetDebuggerFromString() 95e5c89e4eSSatish Balay @*/ 967087cfbeSBarry Smith PetscErrorCode PetscSetDefaultDebugger(void) 97e5c89e4eSSatish Balay { 98e5c89e4eSSatish Balay PetscErrorCode ierr; 99e5c89e4eSSatish Balay 100e5c89e4eSSatish Balay PetscFunctionBegin; 101*4211eb48SBarry Smith #if defined(PETSC_USE_DEBUGGER) 102*4211eb48SBarry Smith ierr = PetscSetDebugger(PETSC_USE_DEBUGGER,PETSC_TRUE);CHKERRQ(ierr); 103e5c89e4eSSatish Balay #endif 1045e96ac45SJed Brown ierr = PetscSetDebugTerminal("xterm -e");CHKERRQ(ierr); 105e5c89e4eSSatish Balay PetscFunctionReturn(0); 106e5c89e4eSSatish Balay } 107e5c89e4eSSatish Balay 108e5c89e4eSSatish Balay static PetscErrorCode PetscCheckDebugger_Private(const char defaultDbg[], const char string[], const char *debugger[]) 109e5c89e4eSSatish Balay { 110ace3abfcSBarry Smith PetscBool exists; 111e5c89e4eSSatish Balay char *f; 112e5c89e4eSSatish Balay PetscErrorCode ierr; 113e5c89e4eSSatish Balay 114e5c89e4eSSatish Balay PetscFunctionBegin; 115e5c89e4eSSatish Balay ierr = PetscStrstr(string, defaultDbg, &f);CHKERRQ(ierr); 116e5c89e4eSSatish Balay if (f) { 117e5c89e4eSSatish Balay ierr = PetscTestFile(string, 'x', &exists);CHKERRQ(ierr); 118a297a907SKarl Rupp if (exists) *debugger = string; 119a297a907SKarl Rupp else *debugger = defaultDbg; 120e5c89e4eSSatish Balay } 121e5c89e4eSSatish Balay PetscFunctionReturn(0); 122e5c89e4eSSatish Balay } 123e5c89e4eSSatish Balay 124e5c89e4eSSatish Balay /*@C 125e5c89e4eSSatish Balay PetscSetDebuggerFromString - Set the complete path for the 126e5c89e4eSSatish Balay debugger for PETSc to use. 127e5c89e4eSSatish Balay 128e5c89e4eSSatish Balay Not collective 129e5c89e4eSSatish Balay 1307c764164SBarry Smith Level: developer 131e5c89e4eSSatish Balay 132e5c89e4eSSatish Balay .seealso: PetscSetDebugger(), PetscSetDefaultDebugger() 133e5c89e4eSSatish Balay @*/ 1347c764164SBarry Smith PetscErrorCode PetscSetDebuggerFromString(const char *string) 135e5c89e4eSSatish Balay { 1360298fd71SBarry Smith const char *debugger = NULL; 137ace3abfcSBarry Smith PetscBool xterm = PETSC_TRUE; 138e5c89e4eSSatish Balay char *f; 139e5c89e4eSSatish Balay PetscErrorCode ierr; 140e5c89e4eSSatish Balay 141e5c89e4eSSatish Balay PetscFunctionBegin; 142e5c89e4eSSatish Balay ierr = PetscStrstr(string, "noxterm", &f);CHKERRQ(ierr); 143e5c89e4eSSatish Balay if (f) xterm = PETSC_FALSE; 144e5c89e4eSSatish Balay ierr = PetscStrstr(string, "ddd", &f);CHKERRQ(ierr); 145e5c89e4eSSatish Balay if (f) xterm = PETSC_FALSE; 146e5c89e4eSSatish Balay ierr = PetscCheckDebugger_Private("xdb", string, &debugger);CHKERRQ(ierr); 147e5c89e4eSSatish Balay ierr = PetscCheckDebugger_Private("dbx", string, &debugger);CHKERRQ(ierr); 148e5c89e4eSSatish Balay ierr = PetscCheckDebugger_Private("xldb", string, &debugger);CHKERRQ(ierr); 149e5c89e4eSSatish Balay ierr = PetscCheckDebugger_Private("gdb", string, &debugger);CHKERRQ(ierr); 150e5c89e4eSSatish Balay ierr = PetscCheckDebugger_Private("idb", string, &debugger);CHKERRQ(ierr); 151e5c89e4eSSatish Balay ierr = PetscCheckDebugger_Private("xxgdb", string, &debugger);CHKERRQ(ierr); 152e5c89e4eSSatish Balay ierr = PetscCheckDebugger_Private("ddd", string, &debugger);CHKERRQ(ierr); 153bf902449SSatish Balay ierr = PetscCheckDebugger_Private("kdbg", string, &debugger);CHKERRQ(ierr); 154e5c89e4eSSatish Balay ierr = PetscCheckDebugger_Private("ups", string, &debugger);CHKERRQ(ierr); 155e5c89e4eSSatish Balay ierr = PetscCheckDebugger_Private("workshop", string, &debugger);CHKERRQ(ierr); 156e5c89e4eSSatish Balay ierr = PetscCheckDebugger_Private("pgdbg", string, &debugger);CHKERRQ(ierr); 157ecbcaa78SBarry Smith ierr = PetscCheckDebugger_Private("pathdb", string, &debugger);CHKERRQ(ierr); 1580e9bae81SBarry Smith ierr = PetscCheckDebugger_Private("lldb", string, &debugger);CHKERRQ(ierr); 159e5c89e4eSSatish Balay 160e5c89e4eSSatish Balay ierr = PetscSetDebugger(debugger, xterm);CHKERRQ(ierr); 161e5c89e4eSSatish Balay PetscFunctionReturn(0); 162e5c89e4eSSatish Balay } 163e5c89e4eSSatish Balay 164e5c89e4eSSatish Balay 165e30d2299SSatish Balay /*@ 166e5c89e4eSSatish Balay PetscAttachDebugger - Attaches the debugger to the running process. 167e5c89e4eSSatish Balay 168e5c89e4eSSatish Balay Not Collective 169e5c89e4eSSatish Balay 170e5c89e4eSSatish Balay Level: advanced 171e5c89e4eSSatish Balay 17295452b02SPatrick Sanan Developer Notes: 17395452b02SPatrick Sanan Since this can be called by the error handler should it be calling SETERRQ() and CHKERRQ()? 174f35f84d1SBarry Smith 175e5c89e4eSSatish Balay .seealso: PetscSetDebugger() 176e5c89e4eSSatish Balay @*/ 1777087cfbeSBarry Smith PetscErrorCode PetscAttachDebugger(void) 178e5c89e4eSSatish Balay { 179e5c89e4eSSatish Balay #if !defined(PETSC_CANNOT_START_DEBUGGER) 180e5c89e4eSSatish Balay int child =0; 181a6d0e24fSJed Brown PetscReal sleeptime=0; 182e5c89e4eSSatish Balay PetscErrorCode ierr; 183e5c89e4eSSatish Balay char program[PETSC_MAX_PATH_LEN],display[256],hostname[64]; 184e5c89e4eSSatish Balay #endif 185e5c89e4eSSatish Balay 186e5c89e4eSSatish Balay PetscFunctionBegin; 187e5c89e4eSSatish Balay #if defined(PETSC_CANNOT_START_DEBUGGER) || !defined(PETSC_HAVE_FORK) 188e5c89e4eSSatish Balay (*PetscErrorPrintf)("System cannot start debugger\n"); 189e5c89e4eSSatish Balay (*PetscErrorPrintf)("On Cray run program in Totalview debugger\n"); 190e5c89e4eSSatish Balay (*PetscErrorPrintf)("On Windows use Developer Studio(MSDEV)\n"); 191fa6b8e38SSatish Balay MPI_Abort(PETSC_COMM_WORLD,1); 192e5c89e4eSSatish Balay #else 193e5c89e4eSSatish Balay ierr = PetscGetDisplay(display,128);CHKERRQ(ierr); 194e5c89e4eSSatish Balay ierr = PetscGetProgramName(program,PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 195e5c89e4eSSatish Balay if (ierr) { 196e5c89e4eSSatish Balay (*PetscErrorPrintf)("Cannot determine program name\n"); 197e5c89e4eSSatish Balay PetscFunctionReturn(1); 198e5c89e4eSSatish Balay } 199e5c89e4eSSatish Balay if (!program[0]) { 200e5c89e4eSSatish Balay (*PetscErrorPrintf)("Cannot determine program name\n"); 201e5c89e4eSSatish Balay PetscFunctionReturn(1); 202e5c89e4eSSatish Balay } 203e5c89e4eSSatish Balay child = (int)fork(); 204e5c89e4eSSatish Balay if (child < 0) { 205e5c89e4eSSatish Balay (*PetscErrorPrintf)("Error in fork() attaching debugger\n"); 206e5c89e4eSSatish Balay PetscFunctionReturn(1); 207e5c89e4eSSatish Balay } 208e5c89e4eSSatish Balay 209e5c89e4eSSatish Balay /* 210e5c89e4eSSatish Balay Swap role the parent and child. This is (I think) so that control c typed 211e5c89e4eSSatish Balay in the debugger goes to the correct process. 212e5c89e4eSSatish Balay */ 213a297a907SKarl Rupp if (child) child = 0; 214a297a907SKarl Rupp else child = (int)getppid(); 215e5c89e4eSSatish Balay 216e5c89e4eSSatish Balay if (child) { /* I am the parent, will run the debugger */ 217e5c89e4eSSatish Balay const char *args[10]; 218e5c89e4eSSatish Balay char pid[10]; 2195e96ac45SJed Brown PetscInt j,jj; 2200e9bae81SBarry Smith PetscBool isdbx,isidb,isxldb,isxxgdb,isups,isxdb,isworkshop,isddd,iskdbg,islldb; 221e5c89e4eSSatish Balay 222e5c89e4eSSatish Balay ierr = PetscGetHostName(hostname,64);CHKERRQ(ierr); 223e5c89e4eSSatish Balay /* 224e5c89e4eSSatish Balay We need to send a continue signal to the "child" process on the 225e5c89e4eSSatish Balay alpha, otherwise it just stays off forever 226e5c89e4eSSatish Balay */ 227e5c89e4eSSatish Balay #if defined(PETSC_NEED_KILL_FOR_DEBUGGER) 228e5c89e4eSSatish Balay kill(child,SIGCONT); 229e5c89e4eSSatish Balay #endif 230e5c89e4eSSatish Balay sprintf(pid,"%d",child); 231e5c89e4eSSatish Balay 232b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"xxgdb",&isxxgdb);CHKERRQ(ierr); 233b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"ddd",&isddd);CHKERRQ(ierr); 234b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"kdbg",&iskdbg);CHKERRQ(ierr); 235b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"ups",&isups);CHKERRQ(ierr); 236b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"xldb",&isxldb);CHKERRQ(ierr); 237b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"xdb",&isxdb);CHKERRQ(ierr); 238b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"dbx",&isdbx);CHKERRQ(ierr); 239b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"idb",&isidb);CHKERRQ(ierr); 240b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"workshop",&isworkshop);CHKERRQ(ierr); 241b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"lldb",&islldb);CHKERRQ(ierr); 242e5c89e4eSSatish Balay 243e5c89e4eSSatish Balay if (isxxgdb || isups || isddd) { 244e5c89e4eSSatish Balay args[1] = program; args[2] = pid; args[3] = "-display"; 245b59f628eSBarry Smith args[0] = PetscDebugger; args[4] = display; args[5] = 0; 246c5888dd7SBarry Smith printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname); 247e5c89e4eSSatish Balay if (execvp(args[0],(char**)args) < 0) { 248e5c89e4eSSatish Balay perror("Unable to start debugger"); 249e5c89e4eSSatish Balay exit(0); 250e5c89e4eSSatish Balay } 251bf902449SSatish Balay } else if (iskdbg) { 252bf902449SSatish Balay args[1] = "-p"; args[2] = pid; args[3] = program; args[4] = "-display"; 253b59f628eSBarry Smith args[0] = PetscDebugger; args[5] = display; args[6] = 0; 254c5888dd7SBarry Smith printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[3],pid,hostname); 255bf902449SSatish Balay if (execvp(args[0],(char**)args) < 0) { 256bf902449SSatish Balay perror("Unable to start debugger"); 257bf902449SSatish Balay exit(0); 258bf902449SSatish Balay } 259e5c89e4eSSatish Balay } else if (isxldb) { 260e5c89e4eSSatish Balay args[1] = "-a"; args[2] = pid; args[3] = program; args[4] = "-display"; 261b59f628eSBarry Smith args[0] = PetscDebugger; args[5] = display; args[6] = 0; 262c5888dd7SBarry Smith printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname); 263e5c89e4eSSatish Balay if (execvp(args[0],(char**)args) < 0) { 264e5c89e4eSSatish Balay perror("Unable to start debugger"); 265e5c89e4eSSatish Balay exit(0); 266e5c89e4eSSatish Balay } 267e5c89e4eSSatish Balay } else if (isworkshop) { 268e5c89e4eSSatish Balay args[1] = "-s"; args[2] = pid; args[3] = "-D"; args[4] = "-"; 269b59f628eSBarry Smith args[0] = PetscDebugger; args[5] = pid; args[6] = "-display"; args[7] = display; args[8] = 0; 270c5888dd7SBarry Smith printf("PETSC: Attaching %s to %s on %s\n",args[0],pid,hostname); 271e5c89e4eSSatish Balay if (execvp(args[0],(char**)args) < 0) { 272e5c89e4eSSatish Balay perror("Unable to start debugger"); 273e5c89e4eSSatish Balay exit(0); 274e5c89e4eSSatish Balay } 2755e96ac45SJed Brown } else { 2765e96ac45SJed Brown j = 0; 2775e96ac45SJed Brown if (Xterm) { 278ace3abfcSBarry Smith PetscBool cmp; 2795e96ac45SJed Brown char *tmp,*tmp1; 2805e96ac45SJed Brown ierr = PetscStrncmp(DebugTerminal,"screen",6,&cmp);CHKERRQ(ierr); 281a5ba6984SMatthew G. Knepley if (!cmp) {ierr = PetscStrncmp(DebugTerminal,"gnome-terminal",6,&cmp);CHKERRQ(ierr);} 2825e96ac45SJed Brown if (cmp) display[0] = 0; /* when using screen, we never pass -display */ 2835e96ac45SJed Brown args[j++] = tmp = DebugTerminal; 2845e96ac45SJed Brown if (display[0]) { 2855e96ac45SJed Brown args[j++] = "-display"; args[j++] = display; 2865e96ac45SJed Brown } 2875e96ac45SJed Brown while (*tmp) { 2885e96ac45SJed Brown ierr = PetscStrchr(tmp,' ',&tmp1);CHKERRQ(ierr); 2895e96ac45SJed Brown if (!tmp1) break; 2905e96ac45SJed Brown *tmp1 = 0; 2915e96ac45SJed Brown tmp = tmp1+1; 2925e96ac45SJed Brown args[j++] = tmp; 2935e96ac45SJed Brown } 2945e96ac45SJed Brown } 295b59f628eSBarry Smith args[j++] = PetscDebugger; 2965e96ac45SJed Brown jj = j; 2975e96ac45SJed Brown args[j++] = program; args[j++] = pid; args[j++] = 0; 2985e96ac45SJed Brown 299e5c89e4eSSatish Balay if (isidb) { 3005e96ac45SJed Brown j = jj; 3015e96ac45SJed Brown args[j++] = "-pid"; 3025e96ac45SJed Brown args[j++] = pid; 3035e96ac45SJed Brown args[j++] = "-gdb"; 3045e96ac45SJed Brown args[j++] = program; 3055e96ac45SJed Brown args[j++] = 0; 306e5c89e4eSSatish Balay } 3070e9bae81SBarry Smith if (islldb) { 3080e9bae81SBarry Smith j = jj; 3090e9bae81SBarry Smith args[j++] = "-p"; 3100e9bae81SBarry Smith args[j++] = pid; 3110e9bae81SBarry Smith args[j++] = 0; 3120e9bae81SBarry Smith } 313e5c89e4eSSatish Balay if (isdbx) { 3145e96ac45SJed Brown j = jj; 3158d359177SBarry Smith #if defined(PETSC_USE_P_FOR_DEBUGGER) 3165e96ac45SJed Brown args[j++] = "-p"; 3175e96ac45SJed Brown args[j++] = pid; 3185e96ac45SJed Brown args[j++] = program; 319e5c89e4eSSatish Balay #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER) 3205e96ac45SJed Brown args[j++] = "-l"; 3215e96ac45SJed Brown args[j++] = "ALL"; 3225e96ac45SJed Brown args[j++] = "-P"; 3235e96ac45SJed Brown args[j++] = pid; 3245e96ac45SJed Brown args[j++] = program; 325e5c89e4eSSatish Balay #elif defined(PETSC_USE_A_FOR_DEBUGGER) 3265e96ac45SJed Brown args[j++] = "-a"; 3275e96ac45SJed Brown args[j++] = pid; 328e5c89e4eSSatish Balay #elif defined(PETSC_USE_PID_FOR_DEBUGGER) 3295e96ac45SJed Brown args[j++] = "-pid"; 3305e96ac45SJed Brown args[j++] = pid; 3315e96ac45SJed Brown args[j++] = program; 332493de400SSatish Balay #else 333493de400SSatish Balay args[j++] = program; 334493de400SSatish Balay args[j++] = pid; 3358d359177SBarry Smith #endif 3365e96ac45SJed Brown args[j++] = 0; 337e5c89e4eSSatish Balay } 3385e96ac45SJed Brown if (Xterm) { 339c5888dd7SBarry 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); 340c5888dd7SBarry Smith else printf("PETSC: Attaching %s to %s on pid %s on %s\n",PetscDebugger,program,pid,hostname); 341a297a907SKarl Rupp 3425e96ac45SJed Brown if (execvp(args[0],(char**)args) < 0) { 3435e96ac45SJed Brown perror("Unable to start debugger in xterm"); 3445e96ac45SJed Brown exit(0); 3455e96ac45SJed Brown } 3465e96ac45SJed Brown } else { 347c5888dd7SBarry Smith printf("PETSC: Attaching %s to %s of pid %s on %s\n",PetscDebugger,program,pid,hostname); 348e5c89e4eSSatish Balay if (execvp(args[0],(char**)args) < 0) { 349e5c89e4eSSatish Balay perror("Unable to start debugger"); 350e5c89e4eSSatish Balay exit(0); 351e5c89e4eSSatish Balay } 352e5c89e4eSSatish Balay } 353e5c89e4eSSatish Balay } 354e5c89e4eSSatish Balay } else { /* I am the child, continue with user code */ 355e5c89e4eSSatish Balay sleeptime = 10; /* default to sleep waiting for debugger */ 356c5929fdfSBarry Smith ierr = PetscOptionsGetReal(NULL,NULL,"-debugger_pause",&sleeptime,NULL);CHKERRQ(ierr); 357e5c89e4eSSatish Balay if (sleeptime < 0) sleeptime = -sleeptime; 358e5c89e4eSSatish Balay #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP) 359e5c89e4eSSatish Balay /* 360e5c89e4eSSatish Balay HP cannot attach process to sleeping debugger, hence count instead 361e5c89e4eSSatish Balay */ 362e5c89e4eSSatish Balay { 363e5c89e4eSSatish Balay PetscReal x = 1.0; 364e5c89e4eSSatish Balay int i =10000000; 365e5c89e4eSSatish Balay while (i--) x++; /* cannot attach to sleeper */ 366e5c89e4eSSatish Balay } 367e5c89e4eSSatish Balay #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY) 368e5c89e4eSSatish Balay /* 369e5c89e4eSSatish Balay IBM sleep may return at anytime, hence must see if there is more time to sleep 370e5c89e4eSSatish Balay */ 371e5c89e4eSSatish Balay { 372e5c89e4eSSatish Balay int left = sleeptime; 373a297a907SKarl Rupp while (left > 0) left = PetscSleep(left) - 1; 374e5c89e4eSSatish Balay } 375e5c89e4eSSatish Balay #else 376e5c89e4eSSatish Balay PetscSleep(sleeptime); 377e5c89e4eSSatish Balay #endif 378e5c89e4eSSatish Balay } 379e5c89e4eSSatish Balay #endif 380e5c89e4eSSatish Balay PetscFunctionReturn(0); 381e5c89e4eSSatish Balay } 382e5c89e4eSSatish Balay 383e5c89e4eSSatish Balay /*@C 384e5c89e4eSSatish Balay PetscAttachDebuggerErrorHandler - Error handler that attaches 385e5c89e4eSSatish Balay a debugger to a running process when an error is detected. 386e5c89e4eSSatish Balay This routine is useful for examining variables, etc. 387e5c89e4eSSatish Balay 388e5c89e4eSSatish Balay Not Collective 389e5c89e4eSSatish Balay 390e5c89e4eSSatish Balay Input Parameters: 391e32f2f54SBarry Smith + comm - communicator over which error occurred 392e32f2f54SBarry Smith . line - the line number of the error (indicated by __LINE__) 393e5c89e4eSSatish Balay . file - the file in which the error was detected (indicated by __FILE__) 394e5c89e4eSSatish Balay . message - an error text string, usually just printed to the screen 395e5c89e4eSSatish Balay . number - the generic error number 396668f157eSBarry Smith . p - PETSC_ERROR_INITIAL if error just detected, otherwise PETSC_ERROR_REPEAT 397e5c89e4eSSatish Balay - ctx - error handler context 398e5c89e4eSSatish Balay 399e5c89e4eSSatish Balay Options Database Keys: 400e5c89e4eSSatish Balay . -on_error_attach_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] - Activates 401e5c89e4eSSatish Balay debugger attachment 402e5c89e4eSSatish Balay 403e5c89e4eSSatish Balay Level: developer 404e5c89e4eSSatish Balay 405e5c89e4eSSatish Balay Notes: 4068d359177SBarry Smith By default the GNU debugger, gdb, is used. Alternatives are lldb, dbx and 407e5c89e4eSSatish Balay xxgdb,xldb (on IBM rs6000), xdb (on HP-UX). 408e5c89e4eSSatish Balay 409e5c89e4eSSatish Balay Most users need not directly employ this routine and the other error 410e5c89e4eSSatish Balay handlers, but can instead use the simplified interface SETERR, which has 411e5c89e4eSSatish Balay the calling sequence 412e32f2f54SBarry Smith $ SETERRQ(PETSC_COMM_SELF,number,p,message) 413e5c89e4eSSatish Balay 414e5c89e4eSSatish Balay Notes for experienced users: 415e5c89e4eSSatish Balay Use PetscPushErrorHandler() to set the desired error handler. The 416e5c89e4eSSatish Balay currently available PETSc error handlers are 417e5c89e4eSSatish Balay $ PetscTraceBackErrorHandler() 418e5c89e4eSSatish Balay $ PetscAttachDebuggerErrorHandler() 419e5c89e4eSSatish Balay $ PetscAbortErrorHandler() 420e5c89e4eSSatish Balay or you may write your own. 421e5c89e4eSSatish Balay 422e5c89e4eSSatish Balay 423e5c89e4eSSatish Balay .seealso: PetscPushErrorHandler(), PetscTraceBackErrorHandler(), 424e5c89e4eSSatish Balay PetscAbortErrorHandler() 425e5c89e4eSSatish Balay @*/ 426efca3c55SSatish Balay PetscErrorCode PetscAttachDebuggerErrorHandler(MPI_Comm comm,int line,const char *fun,const char *file,PetscErrorCode num,PetscErrorType p,const char *mess,void *ctx) 427e5c89e4eSSatish Balay { 428e5c89e4eSSatish Balay PetscErrorCode ierr; 429e5c89e4eSSatish Balay 430e5c89e4eSSatish Balay PetscFunctionBegin; 431e5c89e4eSSatish Balay if (!fun) fun = "User provided function"; 432e5c89e4eSSatish Balay if (!mess) mess = " "; 433e5c89e4eSSatish Balay 434efca3c55SSatish Balay (*PetscErrorPrintf)("%s() line %d in %s %s\n",fun,line,file,mess); 435e5c89e4eSSatish Balay 436e5c89e4eSSatish Balay ierr = PetscAttachDebugger(); 437a297a907SKarl Rupp if (ierr) abort(); /* call abort because don't want to kill other MPI processes that may successfully attach to debugger */ 438e5c89e4eSSatish Balay PetscFunctionReturn(0); 439e5c89e4eSSatish Balay } 440e5c89e4eSSatish Balay 441e5c89e4eSSatish Balay /*@C 442e5c89e4eSSatish Balay PetscStopForDebugger - Prints a message to the screen indicating how to 443e5c89e4eSSatish Balay attach to the process with the debugger and then waits for the 444e5c89e4eSSatish Balay debugger to attach. 445e5c89e4eSSatish Balay 446e5c89e4eSSatish Balay Not Collective 447e5c89e4eSSatish Balay 4488d359177SBarry Smith Level: developer 449e5c89e4eSSatish Balay 45095452b02SPatrick Sanan Notes: 45195452b02SPatrick Sanan This is likely never needed since PetscAttachDebugger() is easier to use and seems to always work. 4528d359177SBarry Smith 45395452b02SPatrick Sanan Developer Notes: 45495452b02SPatrick Sanan Since this can be called by the error handler, should it be calling SETERRQ() and CHKERRQ()? 455f35f84d1SBarry Smith 456e5c89e4eSSatish Balay .seealso: PetscSetDebugger(), PetscAttachDebugger() 457e5c89e4eSSatish Balay @*/ 4587087cfbeSBarry Smith PetscErrorCode PetscStopForDebugger(void) 459e5c89e4eSSatish Balay { 460e5c89e4eSSatish Balay PetscErrorCode ierr; 461e5c89e4eSSatish Balay PetscInt sleeptime=0; 462e5c89e4eSSatish Balay #if !defined(PETSC_CANNOT_START_DEBUGGER) 46351ec2c11SGlenn Hammond int ppid; 464e5c89e4eSSatish Balay PetscMPIInt rank; 465e5c89e4eSSatish Balay char program[PETSC_MAX_PATH_LEN],hostname[256]; 4668d359177SBarry Smith PetscBool isdbx,isxldb,isxxgdb,isddd,iskdbg,isups,isxdb,islldb; 467e5c89e4eSSatish Balay #endif 468e5c89e4eSSatish Balay 469e5c89e4eSSatish Balay PetscFunctionBegin; 470e5c89e4eSSatish Balay #if defined(PETSC_CANNOT_START_DEBUGGER) 471e5c89e4eSSatish Balay (*PetscErrorPrintf)("System cannot start debugger; just continuing program\n"); 472e5c89e4eSSatish Balay #else 473e5c89e4eSSatish Balay ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank); 474f35f84d1SBarry Smith if (ierr) rank = 0; /* ignore error since this may be already in error handler */ 475e5c89e4eSSatish Balay ierr = PetscGetHostName(hostname,256); 476e5c89e4eSSatish Balay if (ierr) { 477e5c89e4eSSatish Balay (*PetscErrorPrintf)("Cannot determine hostname; just continuing program\n"); 478e5c89e4eSSatish Balay PetscFunctionReturn(0); 479e5c89e4eSSatish Balay } 480e5c89e4eSSatish Balay 481e5c89e4eSSatish Balay ierr = PetscGetProgramName(program,256); 482e5c89e4eSSatish Balay if (ierr) { 483e5c89e4eSSatish Balay (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n"); 484e5c89e4eSSatish Balay PetscFunctionReturn(0); 485e5c89e4eSSatish Balay } 486e5c89e4eSSatish Balay if (!program[0]) { 487e5c89e4eSSatish Balay (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n"); 488e5c89e4eSSatish Balay PetscFunctionReturn(0); 489e5c89e4eSSatish Balay } 490e5c89e4eSSatish Balay 491e5c89e4eSSatish Balay ppid = getpid(); 492e5c89e4eSSatish Balay 493b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"xxgdb",&isxxgdb);CHKERRQ(ierr); 494b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"ddd",&isddd);CHKERRQ(ierr); 495b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"kdbg",&iskdbg);CHKERRQ(ierr); 496b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"ups",&isups);CHKERRQ(ierr); 497b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"xldb",&isxldb);CHKERRQ(ierr); 498b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"xdb",&isxdb);CHKERRQ(ierr); 499b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"dbx",&isdbx);CHKERRQ(ierr); 500b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"lldb",&islldb);CHKERRQ(ierr); 501e5c89e4eSSatish Balay 502c5888dd7SBarry Smith if (isxxgdb || isups || isddd || iskdbg) printf("[%d]%s>>%s %s %d\n",rank,hostname,PetscDebugger,program,ppid); 503c5888dd7SBarry Smith else if (isxldb) printf("[%d]%s>>%s -a %d %s\n",rank,hostname,PetscDebugger,ppid,program); 504c5888dd7SBarry Smith else if (islldb) printf("[%d]%s>>%s -p %d\n",rank,hostname,PetscDebugger,ppid); 5058d359177SBarry Smith else if (isdbx) { 506e5c89e4eSSatish Balay #if defined(PETSC_USE_P_FOR_DEBUGGER) 507c5888dd7SBarry Smith printf("[%d]%s>>%s -p %d %s\n",rank,hostname,PetscDebugger,ppid,program); 508e5c89e4eSSatish Balay #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER) 509c5888dd7SBarry Smith printf("[%d]%s>>%s -l ALL -P %d %s\n",rank,hostname,PetscDebugger,ppid,program); 510e5c89e4eSSatish Balay #elif defined(PETSC_USE_A_FOR_DEBUGGER) 511c5888dd7SBarry Smith printf("[%d]%s>>%s -a %d\n",rank,hostname,PetscDebugger,ppid); 512e5c89e4eSSatish Balay #elif defined(PETSC_USE_PID_FOR_DEBUGGER) 513c5888dd7SBarry Smith printf("[%d]%s>>%s -pid %d %s\n",rank,hostname,PetscDebugger,ppid,program); 514e5c89e4eSSatish Balay #else 515c5888dd7SBarry Smith printf("[%d]%s>>%s %s %d\n",rank,hostname,PetscDebugger,program,ppid); 516e5c89e4eSSatish Balay #endif 5178d359177SBarry Smith } 518e5c89e4eSSatish Balay #endif /* PETSC_CANNOT_START_DEBUGGER */ 519e5c89e4eSSatish Balay 520f35f84d1SBarry Smith fflush(stdout); /* ignore error because may already be in error handler */ 521e5c89e4eSSatish Balay 522e5c89e4eSSatish Balay sleeptime = 25; /* default to sleep waiting for debugger */ 523c5929fdfSBarry Smith PetscOptionsGetInt(NULL,NULL,"-debugger_pause",&sleeptime,NULL); /* ignore error because may already be in error handler */ 524e5c89e4eSSatish Balay if (sleeptime < 0) sleeptime = -sleeptime; 525e5c89e4eSSatish Balay #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP) 526e5c89e4eSSatish Balay /* 527e5c89e4eSSatish Balay HP cannot attach process to sleeping debugger, hence count instead 528e5c89e4eSSatish Balay */ 529e5c89e4eSSatish Balay { 530e5c89e4eSSatish Balay PetscReal x = 1.0; 531e5c89e4eSSatish Balay int i =10000000; 532e5c89e4eSSatish Balay while (i--) x++; /* cannot attach to sleeper */ 533e5c89e4eSSatish Balay } 534e5c89e4eSSatish Balay #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY) 535e5c89e4eSSatish Balay /* 536e5c89e4eSSatish Balay IBM sleep may return at anytime, hence must see if there is more time to sleep 537e5c89e4eSSatish Balay */ 538e5c89e4eSSatish Balay { 539e5c89e4eSSatish Balay int left = sleeptime; 540a297a907SKarl Rupp while (left > 0) left = sleep(left) - 1; 541e5c89e4eSSatish Balay } 542e5c89e4eSSatish Balay #else 543e5c89e4eSSatish Balay PetscSleep(sleeptime); 544e5c89e4eSSatish Balay #endif 545e5c89e4eSSatish Balay PetscFunctionReturn(0); 546e5c89e4eSSatish Balay } 547e5c89e4eSSatish Balay 548e5c89e4eSSatish Balay 549e5c89e4eSSatish Balay 550