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: 24a2b725a8SWilliam Gropp . terminal - name of terminal and any flags required to execute a program. 25a5ba6984SMatthew G. Knepley For example "xterm -e", "urxvt -e", "gnome-terminal -x". 265e96ac45SJed Brown 275e96ac45SJed Brown Options Database Keys: 285e96ac45SJed Brown -debug_terminal terminal - use this terminal instead of xterm 295e96ac45SJed Brown 305e96ac45SJed Brown Level: developer 315e96ac45SJed Brown 325e96ac45SJed Brown Notes: 335e96ac45SJed Brown You can start the debugger for all processes in the same GNU screen session. 345e96ac45SJed Brown 35a6404fbfSBarry Smith mpiexec -n 4 ./myapp -start_in_debugger -debug_terminal "screen -X -S debug screen" 365e96ac45SJed Brown 375e96ac45SJed Brown will open 4 windows in the session named "debug". 385e96ac45SJed Brown 395e96ac45SJed Brown Fortran Note: 405e96ac45SJed Brown This routine is not supported in Fortran. 415e96ac45SJed Brown 425e96ac45SJed Brown .seealso: PetscSetDebugger() 435e96ac45SJed Brown @*/ 447087cfbeSBarry Smith PetscErrorCode PetscSetDebugTerminal(const char terminal[]) 455e96ac45SJed Brown { 465e96ac45SJed Brown PetscErrorCode ierr; 475e96ac45SJed Brown 485e96ac45SJed Brown PetscFunctionBegin; 49*589a23caSBarry Smith ierr = PetscStrncpy(DebugTerminal,terminal,sizeof(DebugTerminal));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, 60c4fb7a8fSRichard Tran Mills usually "lldb", "dbx", "gdb", "cuda-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) { 81*589a23caSBarry Smith ierr = PetscStrncpy(PetscDebugger,debugger,sizeof(PetscDebugger));CHKERRQ(ierr); 82e5c89e4eSSatish Balay } 83*589a23caSBarry Smith if(Xterm) 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; 1014211eb48SBarry Smith #if defined(PETSC_USE_DEBUGGER) 1024211eb48SBarry 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); 150c4fb7a8fSRichard Tran Mills ierr = PetscCheckDebugger_Private("cuda-gdb", string, &debugger);CHKERRQ(ierr); 151e5c89e4eSSatish Balay ierr = PetscCheckDebugger_Private("idb", string, &debugger);CHKERRQ(ierr); 152e5c89e4eSSatish Balay ierr = PetscCheckDebugger_Private("xxgdb", string, &debugger);CHKERRQ(ierr); 153e5c89e4eSSatish Balay ierr = PetscCheckDebugger_Private("ddd", string, &debugger);CHKERRQ(ierr); 154bf902449SSatish Balay ierr = PetscCheckDebugger_Private("kdbg", string, &debugger);CHKERRQ(ierr); 155e5c89e4eSSatish Balay ierr = PetscCheckDebugger_Private("ups", string, &debugger);CHKERRQ(ierr); 156e5c89e4eSSatish Balay ierr = PetscCheckDebugger_Private("workshop", string, &debugger);CHKERRQ(ierr); 157e5c89e4eSSatish Balay ierr = PetscCheckDebugger_Private("pgdbg", string, &debugger);CHKERRQ(ierr); 158ecbcaa78SBarry Smith ierr = PetscCheckDebugger_Private("pathdb", string, &debugger);CHKERRQ(ierr); 1590e9bae81SBarry Smith ierr = PetscCheckDebugger_Private("lldb", string, &debugger);CHKERRQ(ierr); 160e5c89e4eSSatish Balay 161e5c89e4eSSatish Balay ierr = PetscSetDebugger(debugger, xterm);CHKERRQ(ierr); 162e5c89e4eSSatish Balay PetscFunctionReturn(0); 163e5c89e4eSSatish Balay } 164e5c89e4eSSatish Balay 165e5c89e4eSSatish Balay 166e30d2299SSatish Balay /*@ 167e5c89e4eSSatish Balay PetscAttachDebugger - Attaches the debugger to the running process. 168e5c89e4eSSatish Balay 169e5c89e4eSSatish Balay Not Collective 170e5c89e4eSSatish Balay 171e5c89e4eSSatish Balay Level: advanced 172e5c89e4eSSatish Balay 17395452b02SPatrick Sanan Developer Notes: 17495452b02SPatrick Sanan Since this can be called by the error handler should it be calling SETERRQ() and CHKERRQ()? 175f35f84d1SBarry Smith 176e5c89e4eSSatish Balay .seealso: PetscSetDebugger() 177e5c89e4eSSatish Balay @*/ 1787087cfbeSBarry Smith PetscErrorCode PetscAttachDebugger(void) 179e5c89e4eSSatish Balay { 180ed50d614Sprj- #if !defined(PETSC_CANNOT_START_DEBUGGER) && defined(PETSC_HAVE_FORK) 181e5c89e4eSSatish Balay int child =0; 182a6d0e24fSJed Brown PetscReal sleeptime=0; 183e5c89e4eSSatish Balay PetscErrorCode ierr; 184e5c89e4eSSatish Balay char program[PETSC_MAX_PATH_LEN],display[256],hostname[64]; 185e5c89e4eSSatish Balay #endif 186e5c89e4eSSatish Balay 187e5c89e4eSSatish Balay PetscFunctionBegin; 188e5c89e4eSSatish Balay #if defined(PETSC_CANNOT_START_DEBUGGER) || !defined(PETSC_HAVE_FORK) 189e5c89e4eSSatish Balay (*PetscErrorPrintf)("System cannot start debugger\n"); 190e5c89e4eSSatish Balay (*PetscErrorPrintf)("On Cray run program in Totalview debugger\n"); 191e5c89e4eSSatish Balay (*PetscErrorPrintf)("On Windows use Developer Studio(MSDEV)\n"); 19241e02c4dSJunchao Zhang PETSCABORT(PETSC_COMM_WORLD,PETSC_ERR_SUP_SYS); 193e5c89e4eSSatish Balay #else 194*589a23caSBarry Smith ierr = PetscGetDisplay(display,sizeof(display));CHKERRQ(ierr); 195*589a23caSBarry Smith ierr = PetscGetProgramName(program,sizeof(program));CHKERRQ(ierr); 196e5c89e4eSSatish Balay if (ierr) { 197e5c89e4eSSatish Balay (*PetscErrorPrintf)("Cannot determine program name\n"); 198e5c89e4eSSatish Balay PetscFunctionReturn(1); 199e5c89e4eSSatish Balay } 200e5c89e4eSSatish Balay if (!program[0]) { 201e5c89e4eSSatish Balay (*PetscErrorPrintf)("Cannot determine program name\n"); 202e5c89e4eSSatish Balay PetscFunctionReturn(1); 203e5c89e4eSSatish Balay } 204e5c89e4eSSatish Balay child = (int)fork(); 205e5c89e4eSSatish Balay if (child < 0) { 206e5c89e4eSSatish Balay (*PetscErrorPrintf)("Error in fork() attaching debugger\n"); 207e5c89e4eSSatish Balay PetscFunctionReturn(1); 208e5c89e4eSSatish Balay } 209e5c89e4eSSatish Balay 210e5c89e4eSSatish Balay /* 211e5c89e4eSSatish Balay Swap role the parent and child. This is (I think) so that control c typed 212e5c89e4eSSatish Balay in the debugger goes to the correct process. 213e5c89e4eSSatish Balay */ 214a297a907SKarl Rupp if (child) child = 0; 215a297a907SKarl Rupp else child = (int)getppid(); 216e5c89e4eSSatish Balay 217e5c89e4eSSatish Balay if (child) { /* I am the parent, will run the debugger */ 218e5c89e4eSSatish Balay const char *args[10]; 219e5c89e4eSSatish Balay char pid[10]; 2205e96ac45SJed Brown PetscInt j,jj; 2210e9bae81SBarry Smith PetscBool isdbx,isidb,isxldb,isxxgdb,isups,isxdb,isworkshop,isddd,iskdbg,islldb; 222e5c89e4eSSatish Balay 223*589a23caSBarry Smith ierr = PetscGetHostName(hostname,sizeof(hostname));CHKERRQ(ierr); 224e5c89e4eSSatish Balay /* 225e5c89e4eSSatish Balay We need to send a continue signal to the "child" process on the 226e5c89e4eSSatish Balay alpha, otherwise it just stays off forever 227e5c89e4eSSatish Balay */ 228e5c89e4eSSatish Balay #if defined(PETSC_NEED_KILL_FOR_DEBUGGER) 229e5c89e4eSSatish Balay kill(child,SIGCONT); 230e5c89e4eSSatish Balay #endif 231e5c89e4eSSatish Balay sprintf(pid,"%d",child); 232e5c89e4eSSatish Balay 233b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"xxgdb",&isxxgdb);CHKERRQ(ierr); 234b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"ddd",&isddd);CHKERRQ(ierr); 235b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"kdbg",&iskdbg);CHKERRQ(ierr); 236b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"ups",&isups);CHKERRQ(ierr); 237b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"xldb",&isxldb);CHKERRQ(ierr); 238b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"xdb",&isxdb);CHKERRQ(ierr); 239b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"dbx",&isdbx);CHKERRQ(ierr); 240b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"idb",&isidb);CHKERRQ(ierr); 241b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"workshop",&isworkshop);CHKERRQ(ierr); 242b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"lldb",&islldb);CHKERRQ(ierr); 243e5c89e4eSSatish Balay 244e5c89e4eSSatish Balay if (isxxgdb || isups || isddd) { 245e5c89e4eSSatish Balay args[1] = program; args[2] = pid; args[3] = "-display"; 24602c9f0b5SLisandro Dalcin args[0] = PetscDebugger; args[4] = display; args[5] = NULL; 247c5888dd7SBarry Smith printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname); 248e5c89e4eSSatish Balay if (execvp(args[0],(char**)args) < 0) { 249e5c89e4eSSatish Balay perror("Unable to start debugger"); 250e5c89e4eSSatish Balay exit(0); 251e5c89e4eSSatish Balay } 252bf902449SSatish Balay } else if (iskdbg) { 253bf902449SSatish Balay args[1] = "-p"; args[2] = pid; args[3] = program; args[4] = "-display"; 25402c9f0b5SLisandro Dalcin args[0] = PetscDebugger; args[5] = display; args[6] = NULL; 255c5888dd7SBarry Smith printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[3],pid,hostname); 256bf902449SSatish Balay if (execvp(args[0],(char**)args) < 0) { 257bf902449SSatish Balay perror("Unable to start debugger"); 258bf902449SSatish Balay exit(0); 259bf902449SSatish Balay } 260e5c89e4eSSatish Balay } else if (isxldb) { 261e5c89e4eSSatish Balay args[1] = "-a"; args[2] = pid; args[3] = program; args[4] = "-display"; 26202c9f0b5SLisandro Dalcin args[0] = PetscDebugger; args[5] = display; args[6] = NULL; 263c5888dd7SBarry Smith printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname); 264e5c89e4eSSatish Balay if (execvp(args[0],(char**)args) < 0) { 265e5c89e4eSSatish Balay perror("Unable to start debugger"); 266e5c89e4eSSatish Balay exit(0); 267e5c89e4eSSatish Balay } 268e5c89e4eSSatish Balay } else if (isworkshop) { 269e5c89e4eSSatish Balay args[1] = "-s"; args[2] = pid; args[3] = "-D"; args[4] = "-"; 27002c9f0b5SLisandro Dalcin args[0] = PetscDebugger; args[5] = pid; args[6] = "-display"; args[7] = display; args[8] = NULL; 271c5888dd7SBarry Smith printf("PETSC: Attaching %s to %s on %s\n",args[0],pid,hostname); 272e5c89e4eSSatish Balay if (execvp(args[0],(char**)args) < 0) { 273e5c89e4eSSatish Balay perror("Unable to start debugger"); 274e5c89e4eSSatish Balay exit(0); 275e5c89e4eSSatish Balay } 2765e96ac45SJed Brown } else { 2775e96ac45SJed Brown j = 0; 2785e96ac45SJed Brown if (Xterm) { 279ace3abfcSBarry Smith PetscBool cmp; 2805e96ac45SJed Brown char *tmp,*tmp1; 2815e96ac45SJed Brown ierr = PetscStrncmp(DebugTerminal,"screen",6,&cmp);CHKERRQ(ierr); 282a5ba6984SMatthew G. Knepley if (!cmp) {ierr = PetscStrncmp(DebugTerminal,"gnome-terminal",6,&cmp);CHKERRQ(ierr);} 2835e96ac45SJed Brown if (cmp) display[0] = 0; /* when using screen, we never pass -display */ 2845e96ac45SJed Brown args[j++] = tmp = DebugTerminal; 2855e96ac45SJed Brown if (display[0]) { 2865e96ac45SJed Brown args[j++] = "-display"; args[j++] = display; 2875e96ac45SJed Brown } 2885e96ac45SJed Brown while (*tmp) { 2895e96ac45SJed Brown ierr = PetscStrchr(tmp,' ',&tmp1);CHKERRQ(ierr); 2905e96ac45SJed Brown if (!tmp1) break; 2915e96ac45SJed Brown *tmp1 = 0; 2925e96ac45SJed Brown tmp = tmp1+1; 2935e96ac45SJed Brown args[j++] = tmp; 2945e96ac45SJed Brown } 2955e96ac45SJed Brown } 296b59f628eSBarry Smith args[j++] = PetscDebugger; 2975e96ac45SJed Brown jj = j; 29802c9f0b5SLisandro Dalcin args[j++] = program; args[j++] = pid; args[j++] = NULL; 2995e96ac45SJed Brown 300e5c89e4eSSatish Balay if (isidb) { 3015e96ac45SJed Brown j = jj; 3025e96ac45SJed Brown args[j++] = "-pid"; 3035e96ac45SJed Brown args[j++] = pid; 3045e96ac45SJed Brown args[j++] = "-gdb"; 3055e96ac45SJed Brown args[j++] = program; 30602c9f0b5SLisandro Dalcin args[j++] = NULL; 307e5c89e4eSSatish Balay } 3080e9bae81SBarry Smith if (islldb) { 3090e9bae81SBarry Smith j = jj; 3100e9bae81SBarry Smith args[j++] = "-p"; 3110e9bae81SBarry Smith args[j++] = pid; 31202c9f0b5SLisandro Dalcin args[j++] = NULL; 3130e9bae81SBarry Smith } 314e5c89e4eSSatish Balay if (isdbx) { 3155e96ac45SJed Brown j = jj; 3168d359177SBarry Smith #if defined(PETSC_USE_P_FOR_DEBUGGER) 3175e96ac45SJed Brown args[j++] = "-p"; 3185e96ac45SJed Brown args[j++] = pid; 3195e96ac45SJed Brown args[j++] = program; 320e5c89e4eSSatish Balay #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER) 3215e96ac45SJed Brown args[j++] = "-l"; 3225e96ac45SJed Brown args[j++] = "ALL"; 3235e96ac45SJed Brown args[j++] = "-P"; 3245e96ac45SJed Brown args[j++] = pid; 3255e96ac45SJed Brown args[j++] = program; 326e5c89e4eSSatish Balay #elif defined(PETSC_USE_A_FOR_DEBUGGER) 3275e96ac45SJed Brown args[j++] = "-a"; 3285e96ac45SJed Brown args[j++] = pid; 329e5c89e4eSSatish Balay #elif defined(PETSC_USE_PID_FOR_DEBUGGER) 3305e96ac45SJed Brown args[j++] = "-pid"; 3315e96ac45SJed Brown args[j++] = pid; 3325e96ac45SJed Brown args[j++] = program; 333493de400SSatish Balay #else 334493de400SSatish Balay args[j++] = program; 335493de400SSatish Balay args[j++] = pid; 3368d359177SBarry Smith #endif 33702c9f0b5SLisandro Dalcin args[j++] = NULL; 338e5c89e4eSSatish Balay } 3395e96ac45SJed Brown if (Xterm) { 340c5888dd7SBarry 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); 341c5888dd7SBarry Smith else printf("PETSC: Attaching %s to %s on pid %s on %s\n",PetscDebugger,program,pid,hostname); 342a297a907SKarl Rupp 3435e96ac45SJed Brown if (execvp(args[0],(char**)args) < 0) { 3445e96ac45SJed Brown perror("Unable to start debugger in xterm"); 3455e96ac45SJed Brown exit(0); 3465e96ac45SJed Brown } 3475e96ac45SJed Brown } else { 348c5888dd7SBarry Smith printf("PETSC: Attaching %s to %s of pid %s on %s\n",PetscDebugger,program,pid,hostname); 349e5c89e4eSSatish Balay if (execvp(args[0],(char**)args) < 0) { 350e5c89e4eSSatish Balay perror("Unable to start debugger"); 351e5c89e4eSSatish Balay exit(0); 352e5c89e4eSSatish Balay } 353e5c89e4eSSatish Balay } 354e5c89e4eSSatish Balay } 355e5c89e4eSSatish Balay } else { /* I am the child, continue with user code */ 356e5c89e4eSSatish Balay sleeptime = 10; /* default to sleep waiting for debugger */ 357c5929fdfSBarry Smith ierr = PetscOptionsGetReal(NULL,NULL,"-debugger_pause",&sleeptime,NULL);CHKERRQ(ierr); 358e5c89e4eSSatish Balay if (sleeptime < 0) sleeptime = -sleeptime; 359e5c89e4eSSatish Balay #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP) 360e5c89e4eSSatish Balay /* 361e5c89e4eSSatish Balay HP cannot attach process to sleeping debugger, hence count instead 362e5c89e4eSSatish Balay */ 363e5c89e4eSSatish Balay { 364e5c89e4eSSatish Balay PetscReal x = 1.0; 365e5c89e4eSSatish Balay int i =10000000; 366e5c89e4eSSatish Balay while (i--) x++; /* cannot attach to sleeper */ 367e5c89e4eSSatish Balay } 368e5c89e4eSSatish Balay #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY) 369e5c89e4eSSatish Balay /* 370e5c89e4eSSatish Balay IBM sleep may return at anytime, hence must see if there is more time to sleep 371e5c89e4eSSatish Balay */ 372e5c89e4eSSatish Balay { 373e5c89e4eSSatish Balay int left = sleeptime; 374a297a907SKarl Rupp while (left > 0) left = PetscSleep(left) - 1; 375e5c89e4eSSatish Balay } 376e5c89e4eSSatish Balay #else 377e5c89e4eSSatish Balay PetscSleep(sleeptime); 378e5c89e4eSSatish Balay #endif 379e5c89e4eSSatish Balay } 380e5c89e4eSSatish Balay #endif 381e5c89e4eSSatish Balay PetscFunctionReturn(0); 382e5c89e4eSSatish Balay } 383e5c89e4eSSatish Balay 384e5c89e4eSSatish Balay /*@C 385e5c89e4eSSatish Balay PetscAttachDebuggerErrorHandler - Error handler that attaches 386e5c89e4eSSatish Balay a debugger to a running process when an error is detected. 387e5c89e4eSSatish Balay This routine is useful for examining variables, etc. 388e5c89e4eSSatish Balay 389e5c89e4eSSatish Balay Not Collective 390e5c89e4eSSatish Balay 391e5c89e4eSSatish Balay Input Parameters: 392e32f2f54SBarry Smith + comm - communicator over which error occurred 393e32f2f54SBarry Smith . line - the line number of the error (indicated by __LINE__) 394e5c89e4eSSatish Balay . file - the file in which the error was detected (indicated by __FILE__) 395e5c89e4eSSatish Balay . message - an error text string, usually just printed to the screen 396e5c89e4eSSatish Balay . number - the generic error number 397668f157eSBarry Smith . p - PETSC_ERROR_INITIAL if error just detected, otherwise PETSC_ERROR_REPEAT 398e5c89e4eSSatish Balay - ctx - error handler context 399e5c89e4eSSatish Balay 400e5c89e4eSSatish Balay Options Database Keys: 401e5c89e4eSSatish Balay . -on_error_attach_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] - Activates 402e5c89e4eSSatish Balay debugger attachment 403e5c89e4eSSatish Balay 404e5c89e4eSSatish Balay Level: developer 405e5c89e4eSSatish Balay 406e5c89e4eSSatish Balay Notes: 407c4fb7a8fSRichard Tran Mills By default the GNU debugger, gdb, is used. Alternatives are cuda-gdb, lldb, dbx and 408e5c89e4eSSatish Balay xxgdb,xldb (on IBM rs6000), xdb (on HP-UX). 409e5c89e4eSSatish Balay 410e5c89e4eSSatish Balay Most users need not directly employ this routine and the other error 411e5c89e4eSSatish Balay handlers, but can instead use the simplified interface SETERR, which has 412e5c89e4eSSatish Balay the calling sequence 413e32f2f54SBarry Smith $ SETERRQ(PETSC_COMM_SELF,number,p,message) 414e5c89e4eSSatish Balay 415e5c89e4eSSatish Balay Notes for experienced users: 416e5c89e4eSSatish Balay Use PetscPushErrorHandler() to set the desired error handler. The 417e5c89e4eSSatish Balay currently available PETSc error handlers are 418e5c89e4eSSatish Balay $ PetscTraceBackErrorHandler() 419e5c89e4eSSatish Balay $ PetscAttachDebuggerErrorHandler() 420e5c89e4eSSatish Balay $ PetscAbortErrorHandler() 421e5c89e4eSSatish Balay or you may write your own. 422e5c89e4eSSatish Balay 423e5c89e4eSSatish Balay 424e5c89e4eSSatish Balay .seealso: PetscPushErrorHandler(), PetscTraceBackErrorHandler(), 425e5c89e4eSSatish Balay PetscAbortErrorHandler() 426e5c89e4eSSatish Balay @*/ 427efca3c55SSatish Balay PetscErrorCode PetscAttachDebuggerErrorHandler(MPI_Comm comm,int line,const char *fun,const char *file,PetscErrorCode num,PetscErrorType p,const char *mess,void *ctx) 428e5c89e4eSSatish Balay { 429e5c89e4eSSatish Balay PetscErrorCode ierr; 430e5c89e4eSSatish Balay 431e5c89e4eSSatish Balay PetscFunctionBegin; 432e5c89e4eSSatish Balay if (!fun) fun = "User provided function"; 433e5c89e4eSSatish Balay if (!mess) mess = " "; 434e5c89e4eSSatish Balay 435efca3c55SSatish Balay (*PetscErrorPrintf)("%s() line %d in %s %s\n",fun,line,file,mess); 436e5c89e4eSSatish Balay 437e5c89e4eSSatish Balay ierr = PetscAttachDebugger(); 438a297a907SKarl Rupp if (ierr) abort(); /* call abort because don't want to kill other MPI processes that may successfully attach to debugger */ 439e5c89e4eSSatish Balay PetscFunctionReturn(0); 440e5c89e4eSSatish Balay } 441e5c89e4eSSatish Balay 442e5c89e4eSSatish Balay /*@C 443e5c89e4eSSatish Balay PetscStopForDebugger - Prints a message to the screen indicating how to 444e5c89e4eSSatish Balay attach to the process with the debugger and then waits for the 445e5c89e4eSSatish Balay debugger to attach. 446e5c89e4eSSatish Balay 447e5c89e4eSSatish Balay Not Collective 448e5c89e4eSSatish Balay 4498d359177SBarry Smith Level: developer 450e5c89e4eSSatish Balay 45195452b02SPatrick Sanan Notes: 45295452b02SPatrick Sanan This is likely never needed since PetscAttachDebugger() is easier to use and seems to always work. 4538d359177SBarry Smith 45495452b02SPatrick Sanan Developer Notes: 45595452b02SPatrick Sanan Since this can be called by the error handler, should it be calling SETERRQ() and CHKERRQ()? 456f35f84d1SBarry Smith 457e5c89e4eSSatish Balay .seealso: PetscSetDebugger(), PetscAttachDebugger() 458e5c89e4eSSatish Balay @*/ 4597087cfbeSBarry Smith PetscErrorCode PetscStopForDebugger(void) 460e5c89e4eSSatish Balay { 461e5c89e4eSSatish Balay PetscErrorCode ierr; 462e5c89e4eSSatish Balay PetscInt sleeptime=0; 463e5c89e4eSSatish Balay #if !defined(PETSC_CANNOT_START_DEBUGGER) 46451ec2c11SGlenn Hammond int ppid; 465e5c89e4eSSatish Balay PetscMPIInt rank; 466e5c89e4eSSatish Balay char program[PETSC_MAX_PATH_LEN],hostname[256]; 4678d359177SBarry Smith PetscBool isdbx,isxldb,isxxgdb,isddd,iskdbg,isups,isxdb,islldb; 468e5c89e4eSSatish Balay #endif 469e5c89e4eSSatish Balay 470e5c89e4eSSatish Balay PetscFunctionBegin; 471e5c89e4eSSatish Balay #if defined(PETSC_CANNOT_START_DEBUGGER) 472e5c89e4eSSatish Balay (*PetscErrorPrintf)("System cannot start debugger; just continuing program\n"); 473e5c89e4eSSatish Balay #else 474e5c89e4eSSatish Balay ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank); 475f35f84d1SBarry Smith if (ierr) rank = 0; /* ignore error since this may be already in error handler */ 476*589a23caSBarry Smith ierr = PetscGetHostName(hostname,sizeof(hostname)); 477e5c89e4eSSatish Balay if (ierr) { 478e5c89e4eSSatish Balay (*PetscErrorPrintf)("Cannot determine hostname; just continuing program\n"); 479e5c89e4eSSatish Balay PetscFunctionReturn(0); 480e5c89e4eSSatish Balay } 481e5c89e4eSSatish Balay 482*589a23caSBarry Smith ierr = PetscGetProgramName(program,sizeof(program)); 483e5c89e4eSSatish Balay if (ierr) { 484e5c89e4eSSatish Balay (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n"); 485e5c89e4eSSatish Balay PetscFunctionReturn(0); 486e5c89e4eSSatish Balay } 487e5c89e4eSSatish Balay if (!program[0]) { 488e5c89e4eSSatish Balay (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n"); 489e5c89e4eSSatish Balay PetscFunctionReturn(0); 490e5c89e4eSSatish Balay } 491e5c89e4eSSatish Balay 492e5c89e4eSSatish Balay ppid = getpid(); 493e5c89e4eSSatish Balay 494b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"xxgdb",&isxxgdb);CHKERRQ(ierr); 495b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"ddd",&isddd);CHKERRQ(ierr); 496b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"kdbg",&iskdbg);CHKERRQ(ierr); 497b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"ups",&isups);CHKERRQ(ierr); 498b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"xldb",&isxldb);CHKERRQ(ierr); 499b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"xdb",&isxdb);CHKERRQ(ierr); 500b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"dbx",&isdbx);CHKERRQ(ierr); 501b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"lldb",&islldb);CHKERRQ(ierr); 502e5c89e4eSSatish Balay 503c5888dd7SBarry Smith if (isxxgdb || isups || isddd || iskdbg) printf("[%d]%s>>%s %s %d\n",rank,hostname,PetscDebugger,program,ppid); 504c5888dd7SBarry Smith else if (isxldb) printf("[%d]%s>>%s -a %d %s\n",rank,hostname,PetscDebugger,ppid,program); 505c5888dd7SBarry Smith else if (islldb) printf("[%d]%s>>%s -p %d\n",rank,hostname,PetscDebugger,ppid); 5068d359177SBarry Smith else if (isdbx) { 507e5c89e4eSSatish Balay #if defined(PETSC_USE_P_FOR_DEBUGGER) 508c5888dd7SBarry Smith printf("[%d]%s>>%s -p %d %s\n",rank,hostname,PetscDebugger,ppid,program); 509e5c89e4eSSatish Balay #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER) 510c5888dd7SBarry Smith printf("[%d]%s>>%s -l ALL -P %d %s\n",rank,hostname,PetscDebugger,ppid,program); 511e5c89e4eSSatish Balay #elif defined(PETSC_USE_A_FOR_DEBUGGER) 512c5888dd7SBarry Smith printf("[%d]%s>>%s -a %d\n",rank,hostname,PetscDebugger,ppid); 513e5c89e4eSSatish Balay #elif defined(PETSC_USE_PID_FOR_DEBUGGER) 514c5888dd7SBarry Smith printf("[%d]%s>>%s -pid %d %s\n",rank,hostname,PetscDebugger,ppid,program); 515e5c89e4eSSatish Balay #else 516c5888dd7SBarry Smith printf("[%d]%s>>%s %s %d\n",rank,hostname,PetscDebugger,program,ppid); 517e5c89e4eSSatish Balay #endif 5188d359177SBarry Smith } 519e5c89e4eSSatish Balay #endif /* PETSC_CANNOT_START_DEBUGGER */ 520e5c89e4eSSatish Balay 521f35f84d1SBarry Smith fflush(stdout); /* ignore error because may already be in error handler */ 522e5c89e4eSSatish Balay 523e5c89e4eSSatish Balay sleeptime = 25; /* default to sleep waiting for debugger */ 524c5929fdfSBarry Smith PetscOptionsGetInt(NULL,NULL,"-debugger_pause",&sleeptime,NULL); /* ignore error because may already be in error handler */ 525e5c89e4eSSatish Balay if (sleeptime < 0) sleeptime = -sleeptime; 526e5c89e4eSSatish Balay #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP) 527e5c89e4eSSatish Balay /* 528e5c89e4eSSatish Balay HP cannot attach process to sleeping debugger, hence count instead 529e5c89e4eSSatish Balay */ 530e5c89e4eSSatish Balay { 531e5c89e4eSSatish Balay PetscReal x = 1.0; 532e5c89e4eSSatish Balay int i =10000000; 533e5c89e4eSSatish Balay while (i--) x++; /* cannot attach to sleeper */ 534e5c89e4eSSatish Balay } 535e5c89e4eSSatish Balay #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY) 536e5c89e4eSSatish Balay /* 537e5c89e4eSSatish Balay IBM sleep may return at anytime, hence must see if there is more time to sleep 538e5c89e4eSSatish Balay */ 539e5c89e4eSSatish Balay { 540e5c89e4eSSatish Balay int left = sleeptime; 541a297a907SKarl Rupp while (left > 0) left = sleep(left) - 1; 542e5c89e4eSSatish Balay } 543e5c89e4eSSatish Balay #else 544e5c89e4eSSatish Balay PetscSleep(sleeptime); 545e5c89e4eSSatish Balay #endif 546e5c89e4eSSatish Balay PetscFunctionReturn(0); 547e5c89e4eSSatish Balay } 548e5c89e4eSSatish Balay 549e5c89e4eSSatish Balay 550e5c89e4eSSatish Balay 551