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; 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, 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) { 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; 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 194e5c89e4eSSatish Balay ierr = PetscGetDisplay(display,128);CHKERRQ(ierr); 195e5c89e4eSSatish Balay ierr = PetscGetProgramName(program,PETSC_MAX_PATH_LEN);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 */ 214*234acd79SBarry Smith #if !defined(PETSC_DO_NOT_SWAP_CHILD_FOR_DEBUGGER) 215a297a907SKarl Rupp if (child) child = 0; 216a297a907SKarl Rupp else child = (int)getppid(); 217*234acd79SBarry Smith #endif 218e5c89e4eSSatish Balay 219e5c89e4eSSatish Balay if (child) { /* I am the parent, will run the debugger */ 220e5c89e4eSSatish Balay const char *args[10]; 221e5c89e4eSSatish Balay char pid[10]; 2225e96ac45SJed Brown PetscInt j,jj; 2230e9bae81SBarry Smith PetscBool isdbx,isidb,isxldb,isxxgdb,isups,isxdb,isworkshop,isddd,iskdbg,islldb; 224e5c89e4eSSatish Balay 225e5c89e4eSSatish Balay ierr = PetscGetHostName(hostname,64);CHKERRQ(ierr); 226e5c89e4eSSatish Balay /* 227e5c89e4eSSatish Balay We need to send a continue signal to the "child" process on the 228e5c89e4eSSatish Balay alpha, otherwise it just stays off forever 229e5c89e4eSSatish Balay */ 230e5c89e4eSSatish Balay #if defined(PETSC_NEED_KILL_FOR_DEBUGGER) 231e5c89e4eSSatish Balay kill(child,SIGCONT); 232e5c89e4eSSatish Balay #endif 233e5c89e4eSSatish Balay sprintf(pid,"%d",child); 234e5c89e4eSSatish Balay 235b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"xxgdb",&isxxgdb);CHKERRQ(ierr); 236b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"ddd",&isddd);CHKERRQ(ierr); 237b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"kdbg",&iskdbg);CHKERRQ(ierr); 238b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"ups",&isups);CHKERRQ(ierr); 239b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"xldb",&isxldb);CHKERRQ(ierr); 240b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"xdb",&isxdb);CHKERRQ(ierr); 241b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"dbx",&isdbx);CHKERRQ(ierr); 242b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"idb",&isidb);CHKERRQ(ierr); 243b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"workshop",&isworkshop);CHKERRQ(ierr); 244b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"lldb",&islldb);CHKERRQ(ierr); 245e5c89e4eSSatish Balay 246e5c89e4eSSatish Balay if (isxxgdb || isups || isddd) { 247e5c89e4eSSatish Balay args[1] = program; args[2] = pid; args[3] = "-display"; 24802c9f0b5SLisandro Dalcin args[0] = PetscDebugger; args[4] = display; args[5] = NULL; 249c5888dd7SBarry Smith printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname); 250e5c89e4eSSatish Balay if (execvp(args[0],(char**)args) < 0) { 251e5c89e4eSSatish Balay perror("Unable to start debugger"); 252e5c89e4eSSatish Balay exit(0); 253e5c89e4eSSatish Balay } 254bf902449SSatish Balay } else if (iskdbg) { 255bf902449SSatish Balay args[1] = "-p"; args[2] = pid; args[3] = program; args[4] = "-display"; 25602c9f0b5SLisandro Dalcin args[0] = PetscDebugger; args[5] = display; args[6] = NULL; 257c5888dd7SBarry Smith printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[3],pid,hostname); 258bf902449SSatish Balay if (execvp(args[0],(char**)args) < 0) { 259bf902449SSatish Balay perror("Unable to start debugger"); 260bf902449SSatish Balay exit(0); 261bf902449SSatish Balay } 262e5c89e4eSSatish Balay } else if (isxldb) { 263e5c89e4eSSatish Balay args[1] = "-a"; args[2] = pid; args[3] = program; args[4] = "-display"; 26402c9f0b5SLisandro Dalcin args[0] = PetscDebugger; args[5] = display; args[6] = NULL; 265c5888dd7SBarry Smith printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname); 266e5c89e4eSSatish Balay if (execvp(args[0],(char**)args) < 0) { 267e5c89e4eSSatish Balay perror("Unable to start debugger"); 268e5c89e4eSSatish Balay exit(0); 269e5c89e4eSSatish Balay } 270e5c89e4eSSatish Balay } else if (isworkshop) { 271e5c89e4eSSatish Balay args[1] = "-s"; args[2] = pid; args[3] = "-D"; args[4] = "-"; 27202c9f0b5SLisandro Dalcin args[0] = PetscDebugger; args[5] = pid; args[6] = "-display"; args[7] = display; args[8] = NULL; 273c5888dd7SBarry Smith printf("PETSC: Attaching %s to %s on %s\n",args[0],pid,hostname); 274e5c89e4eSSatish Balay if (execvp(args[0],(char**)args) < 0) { 275e5c89e4eSSatish Balay perror("Unable to start debugger"); 276e5c89e4eSSatish Balay exit(0); 277e5c89e4eSSatish Balay } 2785e96ac45SJed Brown } else { 2795e96ac45SJed Brown j = 0; 2805e96ac45SJed Brown if (Xterm) { 281ace3abfcSBarry Smith PetscBool cmp; 2825e96ac45SJed Brown char *tmp,*tmp1; 2835e96ac45SJed Brown ierr = PetscStrncmp(DebugTerminal,"screen",6,&cmp);CHKERRQ(ierr); 284a5ba6984SMatthew G. Knepley if (!cmp) {ierr = PetscStrncmp(DebugTerminal,"gnome-terminal",6,&cmp);CHKERRQ(ierr);} 2855e96ac45SJed Brown if (cmp) display[0] = 0; /* when using screen, we never pass -display */ 2865e96ac45SJed Brown args[j++] = tmp = DebugTerminal; 2875e96ac45SJed Brown if (display[0]) { 2885e96ac45SJed Brown args[j++] = "-display"; args[j++] = display; 2895e96ac45SJed Brown } 2905e96ac45SJed Brown while (*tmp) { 2915e96ac45SJed Brown ierr = PetscStrchr(tmp,' ',&tmp1);CHKERRQ(ierr); 2925e96ac45SJed Brown if (!tmp1) break; 2935e96ac45SJed Brown *tmp1 = 0; 2945e96ac45SJed Brown tmp = tmp1+1; 2955e96ac45SJed Brown args[j++] = tmp; 2965e96ac45SJed Brown } 2975e96ac45SJed Brown } 298b59f628eSBarry Smith args[j++] = PetscDebugger; 2995e96ac45SJed Brown jj = j; 30002c9f0b5SLisandro Dalcin args[j++] = program; args[j++] = pid; args[j++] = NULL; 3015e96ac45SJed Brown 302e5c89e4eSSatish Balay if (isidb) { 3035e96ac45SJed Brown j = jj; 3045e96ac45SJed Brown args[j++] = "-pid"; 3055e96ac45SJed Brown args[j++] = pid; 3065e96ac45SJed Brown args[j++] = "-gdb"; 3075e96ac45SJed Brown args[j++] = program; 30802c9f0b5SLisandro Dalcin args[j++] = NULL; 309e5c89e4eSSatish Balay } 3100e9bae81SBarry Smith if (islldb) { 3110e9bae81SBarry Smith j = jj; 3120e9bae81SBarry Smith args[j++] = "-p"; 3130e9bae81SBarry Smith args[j++] = pid; 31402c9f0b5SLisandro Dalcin args[j++] = NULL; 3150e9bae81SBarry Smith } 316e5c89e4eSSatish Balay if (isdbx) { 3175e96ac45SJed Brown j = jj; 3188d359177SBarry Smith #if defined(PETSC_USE_P_FOR_DEBUGGER) 3195e96ac45SJed Brown args[j++] = "-p"; 3205e96ac45SJed Brown args[j++] = pid; 3215e96ac45SJed Brown args[j++] = program; 322e5c89e4eSSatish Balay #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER) 3235e96ac45SJed Brown args[j++] = "-l"; 3245e96ac45SJed Brown args[j++] = "ALL"; 3255e96ac45SJed Brown args[j++] = "-P"; 3265e96ac45SJed Brown args[j++] = pid; 3275e96ac45SJed Brown args[j++] = program; 328e5c89e4eSSatish Balay #elif defined(PETSC_USE_A_FOR_DEBUGGER) 3295e96ac45SJed Brown args[j++] = "-a"; 3305e96ac45SJed Brown args[j++] = pid; 331e5c89e4eSSatish Balay #elif defined(PETSC_USE_PID_FOR_DEBUGGER) 3325e96ac45SJed Brown args[j++] = "-pid"; 3335e96ac45SJed Brown args[j++] = pid; 3345e96ac45SJed Brown args[j++] = program; 335493de400SSatish Balay #else 336493de400SSatish Balay args[j++] = program; 337493de400SSatish Balay args[j++] = pid; 3388d359177SBarry Smith #endif 33902c9f0b5SLisandro Dalcin args[j++] = NULL; 340e5c89e4eSSatish Balay } 3415e96ac45SJed Brown if (Xterm) { 342c5888dd7SBarry 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); 343c5888dd7SBarry Smith else printf("PETSC: Attaching %s to %s on pid %s on %s\n",PetscDebugger,program,pid,hostname); 344a297a907SKarl Rupp 3455e96ac45SJed Brown if (execvp(args[0],(char**)args) < 0) { 3465e96ac45SJed Brown perror("Unable to start debugger in xterm"); 3475e96ac45SJed Brown exit(0); 3485e96ac45SJed Brown } 3495e96ac45SJed Brown } else { 350c5888dd7SBarry Smith printf("PETSC: Attaching %s to %s of pid %s on %s\n",PetscDebugger,program,pid,hostname); 351e5c89e4eSSatish Balay if (execvp(args[0],(char**)args) < 0) { 352e5c89e4eSSatish Balay perror("Unable to start debugger"); 353e5c89e4eSSatish Balay exit(0); 354e5c89e4eSSatish Balay } 355e5c89e4eSSatish Balay } 356e5c89e4eSSatish Balay } 357e5c89e4eSSatish Balay } else { /* I am the child, continue with user code */ 358e5c89e4eSSatish Balay sleeptime = 10; /* default to sleep waiting for debugger */ 359c5929fdfSBarry Smith ierr = PetscOptionsGetReal(NULL,NULL,"-debugger_pause",&sleeptime,NULL);CHKERRQ(ierr); 360e5c89e4eSSatish Balay if (sleeptime < 0) sleeptime = -sleeptime; 361e5c89e4eSSatish Balay #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP) 362e5c89e4eSSatish Balay /* 363e5c89e4eSSatish Balay HP cannot attach process to sleeping debugger, hence count instead 364e5c89e4eSSatish Balay */ 365e5c89e4eSSatish Balay { 366e5c89e4eSSatish Balay PetscReal x = 1.0; 367e5c89e4eSSatish Balay int i =10000000; 368e5c89e4eSSatish Balay while (i--) x++; /* cannot attach to sleeper */ 369e5c89e4eSSatish Balay } 370e5c89e4eSSatish Balay #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY) 371e5c89e4eSSatish Balay /* 372e5c89e4eSSatish Balay IBM sleep may return at anytime, hence must see if there is more time to sleep 373e5c89e4eSSatish Balay */ 374e5c89e4eSSatish Balay { 375e5c89e4eSSatish Balay int left = sleeptime; 376a297a907SKarl Rupp while (left > 0) left = PetscSleep(left) - 1; 377e5c89e4eSSatish Balay } 378e5c89e4eSSatish Balay #else 379e5c89e4eSSatish Balay PetscSleep(sleeptime); 380e5c89e4eSSatish Balay #endif 381e5c89e4eSSatish Balay } 382e5c89e4eSSatish Balay #endif 383e5c89e4eSSatish Balay PetscFunctionReturn(0); 384e5c89e4eSSatish Balay } 385e5c89e4eSSatish Balay 386e5c89e4eSSatish Balay /*@C 387e5c89e4eSSatish Balay PetscAttachDebuggerErrorHandler - Error handler that attaches 388e5c89e4eSSatish Balay a debugger to a running process when an error is detected. 389e5c89e4eSSatish Balay This routine is useful for examining variables, etc. 390e5c89e4eSSatish Balay 391e5c89e4eSSatish Balay Not Collective 392e5c89e4eSSatish Balay 393e5c89e4eSSatish Balay Input Parameters: 394e32f2f54SBarry Smith + comm - communicator over which error occurred 395e32f2f54SBarry Smith . line - the line number of the error (indicated by __LINE__) 396e5c89e4eSSatish Balay . file - the file in which the error was detected (indicated by __FILE__) 397e5c89e4eSSatish Balay . message - an error text string, usually just printed to the screen 398e5c89e4eSSatish Balay . number - the generic error number 399668f157eSBarry Smith . p - PETSC_ERROR_INITIAL if error just detected, otherwise PETSC_ERROR_REPEAT 400e5c89e4eSSatish Balay - ctx - error handler context 401e5c89e4eSSatish Balay 402e5c89e4eSSatish Balay Options Database Keys: 403e5c89e4eSSatish Balay . -on_error_attach_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] - Activates 404e5c89e4eSSatish Balay debugger attachment 405e5c89e4eSSatish Balay 406e5c89e4eSSatish Balay Level: developer 407e5c89e4eSSatish Balay 408e5c89e4eSSatish Balay Notes: 409c4fb7a8fSRichard Tran Mills By default the GNU debugger, gdb, is used. Alternatives are cuda-gdb, lldb, dbx and 410e5c89e4eSSatish Balay xxgdb,xldb (on IBM rs6000), xdb (on HP-UX). 411e5c89e4eSSatish Balay 412e5c89e4eSSatish Balay Most users need not directly employ this routine and the other error 413e5c89e4eSSatish Balay handlers, but can instead use the simplified interface SETERR, which has 414e5c89e4eSSatish Balay the calling sequence 415e32f2f54SBarry Smith $ SETERRQ(PETSC_COMM_SELF,number,p,message) 416e5c89e4eSSatish Balay 417e5c89e4eSSatish Balay Notes for experienced users: 418e5c89e4eSSatish Balay Use PetscPushErrorHandler() to set the desired error handler. The 419e5c89e4eSSatish Balay currently available PETSc error handlers are 420e5c89e4eSSatish Balay $ PetscTraceBackErrorHandler() 421e5c89e4eSSatish Balay $ PetscAttachDebuggerErrorHandler() 422e5c89e4eSSatish Balay $ PetscAbortErrorHandler() 423e5c89e4eSSatish Balay or you may write your own. 424e5c89e4eSSatish Balay 425e5c89e4eSSatish Balay 426e5c89e4eSSatish Balay .seealso: PetscPushErrorHandler(), PetscTraceBackErrorHandler(), 427e5c89e4eSSatish Balay PetscAbortErrorHandler() 428e5c89e4eSSatish Balay @*/ 429efca3c55SSatish Balay PetscErrorCode PetscAttachDebuggerErrorHandler(MPI_Comm comm,int line,const char *fun,const char *file,PetscErrorCode num,PetscErrorType p,const char *mess,void *ctx) 430e5c89e4eSSatish Balay { 431e5c89e4eSSatish Balay PetscErrorCode ierr; 432e5c89e4eSSatish Balay 433e5c89e4eSSatish Balay PetscFunctionBegin; 434e5c89e4eSSatish Balay if (!fun) fun = "User provided function"; 435e5c89e4eSSatish Balay if (!mess) mess = " "; 436e5c89e4eSSatish Balay 437efca3c55SSatish Balay (*PetscErrorPrintf)("%s() line %d in %s %s\n",fun,line,file,mess); 438e5c89e4eSSatish Balay 439e5c89e4eSSatish Balay ierr = PetscAttachDebugger(); 440a297a907SKarl Rupp if (ierr) abort(); /* call abort because don't want to kill other MPI processes that may successfully attach to debugger */ 441e5c89e4eSSatish Balay PetscFunctionReturn(0); 442e5c89e4eSSatish Balay } 443e5c89e4eSSatish Balay 444e5c89e4eSSatish Balay /*@C 445e5c89e4eSSatish Balay PetscStopForDebugger - Prints a message to the screen indicating how to 446e5c89e4eSSatish Balay attach to the process with the debugger and then waits for the 447e5c89e4eSSatish Balay debugger to attach. 448e5c89e4eSSatish Balay 449e5c89e4eSSatish Balay Not Collective 450e5c89e4eSSatish Balay 4518d359177SBarry Smith Level: developer 452e5c89e4eSSatish Balay 45395452b02SPatrick Sanan Notes: 45495452b02SPatrick Sanan This is likely never needed since PetscAttachDebugger() is easier to use and seems to always work. 4558d359177SBarry Smith 45695452b02SPatrick Sanan Developer Notes: 45795452b02SPatrick Sanan Since this can be called by the error handler, should it be calling SETERRQ() and CHKERRQ()? 458f35f84d1SBarry Smith 459e5c89e4eSSatish Balay .seealso: PetscSetDebugger(), PetscAttachDebugger() 460e5c89e4eSSatish Balay @*/ 4617087cfbeSBarry Smith PetscErrorCode PetscStopForDebugger(void) 462e5c89e4eSSatish Balay { 463e5c89e4eSSatish Balay PetscErrorCode ierr; 464e5c89e4eSSatish Balay PetscInt sleeptime=0; 465e5c89e4eSSatish Balay #if !defined(PETSC_CANNOT_START_DEBUGGER) 46651ec2c11SGlenn Hammond int ppid; 467e5c89e4eSSatish Balay PetscMPIInt rank; 468e5c89e4eSSatish Balay char program[PETSC_MAX_PATH_LEN],hostname[256]; 4698d359177SBarry Smith PetscBool isdbx,isxldb,isxxgdb,isddd,iskdbg,isups,isxdb,islldb; 470e5c89e4eSSatish Balay #endif 471e5c89e4eSSatish Balay 472e5c89e4eSSatish Balay PetscFunctionBegin; 473e5c89e4eSSatish Balay #if defined(PETSC_CANNOT_START_DEBUGGER) 474e5c89e4eSSatish Balay (*PetscErrorPrintf)("System cannot start debugger; just continuing program\n"); 475e5c89e4eSSatish Balay #else 476e5c89e4eSSatish Balay ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank); 477f35f84d1SBarry Smith if (ierr) rank = 0; /* ignore error since this may be already in error handler */ 478e5c89e4eSSatish Balay ierr = PetscGetHostName(hostname,256); 479e5c89e4eSSatish Balay if (ierr) { 480e5c89e4eSSatish Balay (*PetscErrorPrintf)("Cannot determine hostname; just continuing program\n"); 481e5c89e4eSSatish Balay PetscFunctionReturn(0); 482e5c89e4eSSatish Balay } 483e5c89e4eSSatish Balay 484e5c89e4eSSatish Balay ierr = PetscGetProgramName(program,256); 485e5c89e4eSSatish Balay if (ierr) { 486e5c89e4eSSatish Balay (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n"); 487e5c89e4eSSatish Balay PetscFunctionReturn(0); 488e5c89e4eSSatish Balay } 489e5c89e4eSSatish Balay if (!program[0]) { 490e5c89e4eSSatish Balay (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n"); 491e5c89e4eSSatish Balay PetscFunctionReturn(0); 492e5c89e4eSSatish Balay } 493e5c89e4eSSatish Balay 494e5c89e4eSSatish Balay ppid = getpid(); 495e5c89e4eSSatish Balay 496b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"xxgdb",&isxxgdb);CHKERRQ(ierr); 497b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"ddd",&isddd);CHKERRQ(ierr); 498b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"kdbg",&iskdbg);CHKERRQ(ierr); 499b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"ups",&isups);CHKERRQ(ierr); 500b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"xldb",&isxldb);CHKERRQ(ierr); 501b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"xdb",&isxdb);CHKERRQ(ierr); 502b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"dbx",&isdbx);CHKERRQ(ierr); 503b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"lldb",&islldb);CHKERRQ(ierr); 504e5c89e4eSSatish Balay 505c5888dd7SBarry Smith if (isxxgdb || isups || isddd || iskdbg) printf("[%d]%s>>%s %s %d\n",rank,hostname,PetscDebugger,program,ppid); 506c5888dd7SBarry Smith else if (isxldb) printf("[%d]%s>>%s -a %d %s\n",rank,hostname,PetscDebugger,ppid,program); 507c5888dd7SBarry Smith else if (islldb) printf("[%d]%s>>%s -p %d\n",rank,hostname,PetscDebugger,ppid); 5088d359177SBarry Smith else if (isdbx) { 509e5c89e4eSSatish Balay #if defined(PETSC_USE_P_FOR_DEBUGGER) 510c5888dd7SBarry Smith printf("[%d]%s>>%s -p %d %s\n",rank,hostname,PetscDebugger,ppid,program); 511e5c89e4eSSatish Balay #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER) 512c5888dd7SBarry Smith printf("[%d]%s>>%s -l ALL -P %d %s\n",rank,hostname,PetscDebugger,ppid,program); 513e5c89e4eSSatish Balay #elif defined(PETSC_USE_A_FOR_DEBUGGER) 514c5888dd7SBarry Smith printf("[%d]%s>>%s -a %d\n",rank,hostname,PetscDebugger,ppid); 515e5c89e4eSSatish Balay #elif defined(PETSC_USE_PID_FOR_DEBUGGER) 516c5888dd7SBarry Smith printf("[%d]%s>>%s -pid %d %s\n",rank,hostname,PetscDebugger,ppid,program); 517e5c89e4eSSatish Balay #else 518c5888dd7SBarry Smith printf("[%d]%s>>%s %s %d\n",rank,hostname,PetscDebugger,program,ppid); 519e5c89e4eSSatish Balay #endif 5208d359177SBarry Smith } 521e5c89e4eSSatish Balay #endif /* PETSC_CANNOT_START_DEBUGGER */ 522e5c89e4eSSatish Balay 523f35f84d1SBarry Smith fflush(stdout); /* ignore error because may already be in error handler */ 524e5c89e4eSSatish Balay 525e5c89e4eSSatish Balay sleeptime = 25; /* default to sleep waiting for debugger */ 526c5929fdfSBarry Smith PetscOptionsGetInt(NULL,NULL,"-debugger_pause",&sleeptime,NULL); /* ignore error because may already be in error handler */ 527e5c89e4eSSatish Balay if (sleeptime < 0) sleeptime = -sleeptime; 528e5c89e4eSSatish Balay #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP) 529e5c89e4eSSatish Balay /* 530e5c89e4eSSatish Balay HP cannot attach process to sleeping debugger, hence count instead 531e5c89e4eSSatish Balay */ 532e5c89e4eSSatish Balay { 533e5c89e4eSSatish Balay PetscReal x = 1.0; 534e5c89e4eSSatish Balay int i =10000000; 535e5c89e4eSSatish Balay while (i--) x++; /* cannot attach to sleeper */ 536e5c89e4eSSatish Balay } 537e5c89e4eSSatish Balay #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY) 538e5c89e4eSSatish Balay /* 539e5c89e4eSSatish Balay IBM sleep may return at anytime, hence must see if there is more time to sleep 540e5c89e4eSSatish Balay */ 541e5c89e4eSSatish Balay { 542e5c89e4eSSatish Balay int left = sleeptime; 543a297a907SKarl Rupp while (left > 0) left = sleep(left) - 1; 544e5c89e4eSSatish Balay } 545e5c89e4eSSatish Balay #else 546e5c89e4eSSatish Balay PetscSleep(sleeptime); 547e5c89e4eSSatish Balay #endif 548e5c89e4eSSatish Balay PetscFunctionReturn(0); 549e5c89e4eSSatish Balay } 550e5c89e4eSSatish Balay 551e5c89e4eSSatish Balay 552e5c89e4eSSatish Balay 553