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; 17*2a2a2941SBarry Smith PetscBool petscwaitonerror = PETSC_FALSE; 18e5c89e4eSSatish Balay 195e96ac45SJed Brown /*@C 205e96ac45SJed Brown PetscSetDebugTerminal - Sets the terminal to use (instead of xterm) for debugging. 215e96ac45SJed Brown 225e96ac45SJed Brown Not Collective 235e96ac45SJed Brown 245e96ac45SJed Brown Input Parameters: 25a2b725a8SWilliam Gropp . terminal - name of terminal and any flags required to execute a program. 26a5ba6984SMatthew G. Knepley For example "xterm -e", "urxvt -e", "gnome-terminal -x". 275e96ac45SJed Brown 285e96ac45SJed Brown Options Database Keys: 295e96ac45SJed Brown -debug_terminal terminal - use this terminal instead of xterm 305e96ac45SJed Brown 315e96ac45SJed Brown Level: developer 325e96ac45SJed Brown 335e96ac45SJed Brown Notes: 345e96ac45SJed Brown You can start the debugger for all processes in the same GNU screen session. 355e96ac45SJed Brown 36a6404fbfSBarry Smith mpiexec -n 4 ./myapp -start_in_debugger -debug_terminal "screen -X -S debug screen" 375e96ac45SJed Brown 385e96ac45SJed Brown will open 4 windows in the session named "debug". 395e96ac45SJed Brown 405e96ac45SJed Brown Fortran Note: 415e96ac45SJed Brown This routine is not supported in Fortran. 425e96ac45SJed Brown 435e96ac45SJed Brown .seealso: PetscSetDebugger() 445e96ac45SJed Brown @*/ 457087cfbeSBarry Smith PetscErrorCode PetscSetDebugTerminal(const char terminal[]) 465e96ac45SJed Brown { 475e96ac45SJed Brown PetscErrorCode ierr; 485e96ac45SJed Brown 495e96ac45SJed Brown PetscFunctionBegin; 50589a23caSBarry Smith ierr = PetscStrncpy(DebugTerminal,terminal,sizeof(DebugTerminal));CHKERRQ(ierr); 515e96ac45SJed Brown PetscFunctionReturn(0); 525e96ac45SJed Brown } 535e96ac45SJed Brown 54e5c89e4eSSatish Balay /*@C 55e5c89e4eSSatish Balay PetscSetDebugger - Sets options associated with the debugger. 56e5c89e4eSSatish Balay 57e5c89e4eSSatish Balay Not Collective 58e5c89e4eSSatish Balay 59e5c89e4eSSatish Balay Input Parameters: 60e5c89e4eSSatish Balay + debugger - name of debugger, which should be in your path, 61c4fb7a8fSRichard Tran Mills usually "lldb", "dbx", "gdb", "cuda-gdb", "idb", "xxgdb", "kdgb" or "ddd". Also, HP-UX 62e5c89e4eSSatish Balay supports "xdb", and IBM rs6000 supports "xldb". 63e5c89e4eSSatish Balay 648d359177SBarry Smith - xterm - flag to indicate debugger window, set to either PETSC_TRUE (to indicate 658d359177SBarry Smith debugger should be started in a new xterm) or PETSC_FALSE (to start debugger 668d359177SBarry Smith in initial window (the option PETSC_FALSE makes no sense when using more 678d359177SBarry Smith than one MPI process.) 68e5c89e4eSSatish Balay 69e5c89e4eSSatish Balay Level: developer 70e5c89e4eSSatish Balay 71e5c89e4eSSatish Balay Fortran Note: 72e5c89e4eSSatish Balay This routine is not supported in Fortran. 73e5c89e4eSSatish Balay 74e5c89e4eSSatish Balay .seealso: PetscAttachDebugger(), PetscAttachDebuggerErrorHandler() 75e5c89e4eSSatish Balay @*/ 767087cfbeSBarry Smith PetscErrorCode PetscSetDebugger(const char debugger[],PetscBool xterm) 77e5c89e4eSSatish Balay { 78e5c89e4eSSatish Balay PetscErrorCode ierr; 79e5c89e4eSSatish Balay 80e5c89e4eSSatish Balay PetscFunctionBegin; 81e5c89e4eSSatish Balay if (debugger) { 82589a23caSBarry Smith ierr = PetscStrncpy(PetscDebugger,debugger,sizeof(PetscDebugger));CHKERRQ(ierr); 83e5c89e4eSSatish Balay } 84589a23caSBarry Smith if (Xterm) Xterm = xterm; 85e5c89e4eSSatish Balay PetscFunctionReturn(0); 86e5c89e4eSSatish Balay } 87e5c89e4eSSatish Balay 888d359177SBarry Smith /*@C 89f35f84d1SBarry Smith PetscSetDefaultDebugger - Causes PETSc to use its default debugger. 90e5c89e4eSSatish Balay 91e5c89e4eSSatish Balay Not collective 92e5c89e4eSSatish Balay 938d359177SBarry Smith Level: developer 94e5c89e4eSSatish Balay 95e5c89e4eSSatish Balay .seealso: PetscSetDebugger(), PetscSetDebuggerFromString() 96e5c89e4eSSatish Balay @*/ 977087cfbeSBarry Smith PetscErrorCode PetscSetDefaultDebugger(void) 98e5c89e4eSSatish Balay { 99e5c89e4eSSatish Balay PetscErrorCode ierr; 100e5c89e4eSSatish Balay 101e5c89e4eSSatish Balay PetscFunctionBegin; 1024211eb48SBarry Smith #if defined(PETSC_USE_DEBUGGER) 1034211eb48SBarry Smith ierr = PetscSetDebugger(PETSC_USE_DEBUGGER,PETSC_TRUE);CHKERRQ(ierr); 104e5c89e4eSSatish Balay #endif 1055e96ac45SJed Brown ierr = PetscSetDebugTerminal("xterm -e");CHKERRQ(ierr); 106e5c89e4eSSatish Balay PetscFunctionReturn(0); 107e5c89e4eSSatish Balay } 108e5c89e4eSSatish Balay 109e5c89e4eSSatish Balay static PetscErrorCode PetscCheckDebugger_Private(const char defaultDbg[], const char string[], const char *debugger[]) 110e5c89e4eSSatish Balay { 111ace3abfcSBarry Smith PetscBool exists; 112e5c89e4eSSatish Balay char *f; 113e5c89e4eSSatish Balay PetscErrorCode ierr; 114e5c89e4eSSatish Balay 115e5c89e4eSSatish Balay PetscFunctionBegin; 116e5c89e4eSSatish Balay ierr = PetscStrstr(string, defaultDbg, &f);CHKERRQ(ierr); 117e5c89e4eSSatish Balay if (f) { 118e5c89e4eSSatish Balay ierr = PetscTestFile(string, 'x', &exists);CHKERRQ(ierr); 119a297a907SKarl Rupp if (exists) *debugger = string; 120a297a907SKarl Rupp else *debugger = defaultDbg; 121e5c89e4eSSatish Balay } 122e5c89e4eSSatish Balay PetscFunctionReturn(0); 123e5c89e4eSSatish Balay } 124e5c89e4eSSatish Balay 125e5c89e4eSSatish Balay /*@C 126e5c89e4eSSatish Balay PetscSetDebuggerFromString - Set the complete path for the 127e5c89e4eSSatish Balay debugger for PETSc to use. 128e5c89e4eSSatish Balay 129e5c89e4eSSatish Balay Not collective 130e5c89e4eSSatish Balay 1317c764164SBarry Smith Level: developer 132e5c89e4eSSatish Balay 133e5c89e4eSSatish Balay .seealso: PetscSetDebugger(), PetscSetDefaultDebugger() 134e5c89e4eSSatish Balay @*/ 1357c764164SBarry Smith PetscErrorCode PetscSetDebuggerFromString(const char *string) 136e5c89e4eSSatish Balay { 1370298fd71SBarry Smith const char *debugger = NULL; 138ace3abfcSBarry Smith PetscBool xterm = PETSC_TRUE; 139e5c89e4eSSatish Balay char *f; 140e5c89e4eSSatish Balay PetscErrorCode ierr; 141e5c89e4eSSatish Balay 142e5c89e4eSSatish Balay PetscFunctionBegin; 143e5c89e4eSSatish Balay ierr = PetscStrstr(string, "noxterm", &f);CHKERRQ(ierr); 144e5c89e4eSSatish Balay if (f) xterm = PETSC_FALSE; 145e5c89e4eSSatish Balay ierr = PetscStrstr(string, "ddd", &f);CHKERRQ(ierr); 146e5c89e4eSSatish Balay if (f) xterm = PETSC_FALSE; 147e5c89e4eSSatish Balay ierr = PetscCheckDebugger_Private("xdb", string, &debugger);CHKERRQ(ierr); 148e5c89e4eSSatish Balay ierr = PetscCheckDebugger_Private("dbx", string, &debugger);CHKERRQ(ierr); 149e5c89e4eSSatish Balay ierr = PetscCheckDebugger_Private("xldb", string, &debugger);CHKERRQ(ierr); 150e5c89e4eSSatish Balay ierr = PetscCheckDebugger_Private("gdb", string, &debugger);CHKERRQ(ierr); 151c4fb7a8fSRichard Tran Mills ierr = PetscCheckDebugger_Private("cuda-gdb", string, &debugger);CHKERRQ(ierr); 152e5c89e4eSSatish Balay ierr = PetscCheckDebugger_Private("idb", string, &debugger);CHKERRQ(ierr); 153e5c89e4eSSatish Balay ierr = PetscCheckDebugger_Private("xxgdb", string, &debugger);CHKERRQ(ierr); 154e5c89e4eSSatish Balay ierr = PetscCheckDebugger_Private("ddd", string, &debugger);CHKERRQ(ierr); 155bf902449SSatish Balay ierr = PetscCheckDebugger_Private("kdbg", string, &debugger);CHKERRQ(ierr); 156e5c89e4eSSatish Balay ierr = PetscCheckDebugger_Private("ups", string, &debugger);CHKERRQ(ierr); 157e5c89e4eSSatish Balay ierr = PetscCheckDebugger_Private("workshop", string, &debugger);CHKERRQ(ierr); 158e5c89e4eSSatish Balay ierr = PetscCheckDebugger_Private("pgdbg", string, &debugger);CHKERRQ(ierr); 159ecbcaa78SBarry Smith ierr = PetscCheckDebugger_Private("pathdb", string, &debugger);CHKERRQ(ierr); 1600e9bae81SBarry Smith ierr = PetscCheckDebugger_Private("lldb", string, &debugger);CHKERRQ(ierr); 161e5c89e4eSSatish Balay 162e5c89e4eSSatish Balay ierr = PetscSetDebugger(debugger, xterm);CHKERRQ(ierr); 163e5c89e4eSSatish Balay PetscFunctionReturn(0); 164e5c89e4eSSatish Balay } 165e5c89e4eSSatish Balay 166*2a2a2941SBarry Smith /*@ 167*2a2a2941SBarry Smith PetscWaitOnError - If an error is detected and the process would normally exit the main program with MPI_Abort() sleep instead 168*2a2a2941SBarry Smith of exiting. 169*2a2a2941SBarry Smith 170*2a2a2941SBarry Smith Not Collective 171*2a2a2941SBarry Smith 172*2a2a2941SBarry Smith Level: advanced 173*2a2a2941SBarry Smith 174*2a2a2941SBarry Smith Notes: 175*2a2a2941SBarry 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 176*2a2a2941SBarry Smith killing the user's debugging sessions. 177*2a2a2941SBarry Smith 178*2a2a2941SBarry Smith 179*2a2a2941SBarry Smith .seealso: PetscSetDebugger(), PetscAttachDebugger() 180*2a2a2941SBarry Smith @*/ 181*2a2a2941SBarry Smith PetscErrorCode PetscWaitOnError() 182*2a2a2941SBarry Smith { 183*2a2a2941SBarry Smith petscwaitonerror = PETSC_TRUE; 184*2a2a2941SBarry Smith return 0; 185*2a2a2941SBarry Smith } 186e5c89e4eSSatish Balay 187e30d2299SSatish Balay /*@ 188e5c89e4eSSatish Balay PetscAttachDebugger - Attaches the debugger to the running process. 189e5c89e4eSSatish Balay 190e5c89e4eSSatish Balay Not Collective 191e5c89e4eSSatish Balay 192e5c89e4eSSatish Balay Level: advanced 193e5c89e4eSSatish Balay 19495452b02SPatrick Sanan Developer Notes: 19595452b02SPatrick Sanan Since this can be called by the error handler should it be calling SETERRQ() and CHKERRQ()? 196f35f84d1SBarry Smith 197e5c89e4eSSatish Balay .seealso: PetscSetDebugger() 198e5c89e4eSSatish Balay @*/ 1997087cfbeSBarry Smith PetscErrorCode PetscAttachDebugger(void) 200e5c89e4eSSatish Balay { 201ed50d614Sprj- #if !defined(PETSC_CANNOT_START_DEBUGGER) && defined(PETSC_HAVE_FORK) 202e5c89e4eSSatish Balay int child =0; 203a6d0e24fSJed Brown PetscReal sleeptime=0; 204e5c89e4eSSatish Balay PetscErrorCode ierr; 205e5c89e4eSSatish Balay char program[PETSC_MAX_PATH_LEN],display[256],hostname[64]; 206e5c89e4eSSatish Balay #endif 207e5c89e4eSSatish Balay 208e5c89e4eSSatish Balay PetscFunctionBegin; 209e5c89e4eSSatish Balay #if defined(PETSC_CANNOT_START_DEBUGGER) || !defined(PETSC_HAVE_FORK) 210e5c89e4eSSatish Balay (*PetscErrorPrintf)("System cannot start debugger\n"); 211e5c89e4eSSatish Balay (*PetscErrorPrintf)("On Cray run program in Totalview debugger\n"); 212e5c89e4eSSatish Balay (*PetscErrorPrintf)("On Windows use Developer Studio(MSDEV)\n"); 21341e02c4dSJunchao Zhang PETSCABORT(PETSC_COMM_WORLD,PETSC_ERR_SUP_SYS); 214e5c89e4eSSatish Balay #else 215589a23caSBarry Smith ierr = PetscGetDisplay(display,sizeof(display));CHKERRQ(ierr); 216589a23caSBarry Smith ierr = PetscGetProgramName(program,sizeof(program));CHKERRQ(ierr); 217e5c89e4eSSatish Balay if (ierr) { 218e5c89e4eSSatish Balay (*PetscErrorPrintf)("Cannot determine program name\n"); 219e5c89e4eSSatish Balay PetscFunctionReturn(1); 220e5c89e4eSSatish Balay } 221e5c89e4eSSatish Balay if (!program[0]) { 222e5c89e4eSSatish Balay (*PetscErrorPrintf)("Cannot determine program name\n"); 223e5c89e4eSSatish Balay PetscFunctionReturn(1); 224e5c89e4eSSatish Balay } 225e5c89e4eSSatish Balay child = (int)fork(); 226e5c89e4eSSatish Balay if (child < 0) { 227e5c89e4eSSatish Balay (*PetscErrorPrintf)("Error in fork() attaching debugger\n"); 228e5c89e4eSSatish Balay PetscFunctionReturn(1); 229e5c89e4eSSatish Balay } 230e5c89e4eSSatish Balay 231e5c89e4eSSatish Balay /* 232e5c89e4eSSatish Balay Swap role the parent and child. This is (I think) so that control c typed 233e5c89e4eSSatish Balay in the debugger goes to the correct process. 234e5c89e4eSSatish Balay */ 235234acd79SBarry Smith #if !defined(PETSC_DO_NOT_SWAP_CHILD_FOR_DEBUGGER) 236a297a907SKarl Rupp if (child) child = 0; 237a297a907SKarl Rupp else child = (int)getppid(); 238234acd79SBarry Smith #endif 239e5c89e4eSSatish Balay 240e5c89e4eSSatish Balay if (child) { /* I am the parent, will run the debugger */ 241e5c89e4eSSatish Balay const char *args[10]; 242e5c89e4eSSatish Balay char pid[10]; 2435e96ac45SJed Brown PetscInt j,jj; 2440e9bae81SBarry Smith PetscBool isdbx,isidb,isxldb,isxxgdb,isups,isxdb,isworkshop,isddd,iskdbg,islldb; 245e5c89e4eSSatish Balay 246589a23caSBarry Smith ierr = PetscGetHostName(hostname,sizeof(hostname));CHKERRQ(ierr); 247e5c89e4eSSatish Balay /* 248e5c89e4eSSatish Balay We need to send a continue signal to the "child" process on the 249e5c89e4eSSatish Balay alpha, otherwise it just stays off forever 250e5c89e4eSSatish Balay */ 251e5c89e4eSSatish Balay #if defined(PETSC_NEED_KILL_FOR_DEBUGGER) 252e5c89e4eSSatish Balay kill(child,SIGCONT); 253e5c89e4eSSatish Balay #endif 254e5c89e4eSSatish Balay sprintf(pid,"%d",child); 255e5c89e4eSSatish Balay 256b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"xxgdb",&isxxgdb);CHKERRQ(ierr); 257b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"ddd",&isddd);CHKERRQ(ierr); 258b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"kdbg",&iskdbg);CHKERRQ(ierr); 259b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"ups",&isups);CHKERRQ(ierr); 260b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"xldb",&isxldb);CHKERRQ(ierr); 261b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"xdb",&isxdb);CHKERRQ(ierr); 262b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"dbx",&isdbx);CHKERRQ(ierr); 263b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"idb",&isidb);CHKERRQ(ierr); 264b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"workshop",&isworkshop);CHKERRQ(ierr); 265b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"lldb",&islldb);CHKERRQ(ierr); 266e5c89e4eSSatish Balay 267e5c89e4eSSatish Balay if (isxxgdb || isups || isddd) { 268e5c89e4eSSatish Balay args[1] = program; args[2] = pid; args[3] = "-display"; 26902c9f0b5SLisandro Dalcin args[0] = PetscDebugger; args[4] = display; args[5] = NULL; 270c5888dd7SBarry Smith printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname); 271e5c89e4eSSatish Balay if (execvp(args[0],(char**)args) < 0) { 272e5c89e4eSSatish Balay perror("Unable to start debugger"); 273e5c89e4eSSatish Balay exit(0); 274e5c89e4eSSatish Balay } 275bf902449SSatish Balay } else if (iskdbg) { 276bf902449SSatish Balay args[1] = "-p"; args[2] = pid; args[3] = program; args[4] = "-display"; 27702c9f0b5SLisandro Dalcin args[0] = PetscDebugger; args[5] = display; args[6] = NULL; 278c5888dd7SBarry Smith printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[3],pid,hostname); 279bf902449SSatish Balay if (execvp(args[0],(char**)args) < 0) { 280bf902449SSatish Balay perror("Unable to start debugger"); 281bf902449SSatish Balay exit(0); 282bf902449SSatish Balay } 283e5c89e4eSSatish Balay } else if (isxldb) { 284e5c89e4eSSatish Balay args[1] = "-a"; args[2] = pid; args[3] = program; args[4] = "-display"; 28502c9f0b5SLisandro Dalcin args[0] = PetscDebugger; args[5] = display; args[6] = NULL; 286c5888dd7SBarry Smith printf("PETSC: Attaching %s to %s %s on %s\n",args[0],args[1],pid,hostname); 287e5c89e4eSSatish Balay if (execvp(args[0],(char**)args) < 0) { 288e5c89e4eSSatish Balay perror("Unable to start debugger"); 289e5c89e4eSSatish Balay exit(0); 290e5c89e4eSSatish Balay } 291e5c89e4eSSatish Balay } else if (isworkshop) { 292e5c89e4eSSatish Balay args[1] = "-s"; args[2] = pid; args[3] = "-D"; args[4] = "-"; 29302c9f0b5SLisandro Dalcin args[0] = PetscDebugger; args[5] = pid; args[6] = "-display"; args[7] = display; args[8] = NULL; 294c5888dd7SBarry Smith printf("PETSC: Attaching %s to %s on %s\n",args[0],pid,hostname); 295e5c89e4eSSatish Balay if (execvp(args[0],(char**)args) < 0) { 296e5c89e4eSSatish Balay perror("Unable to start debugger"); 297e5c89e4eSSatish Balay exit(0); 298e5c89e4eSSatish Balay } 2995e96ac45SJed Brown } else { 3005e96ac45SJed Brown j = 0; 3015e96ac45SJed Brown if (Xterm) { 302ace3abfcSBarry Smith PetscBool cmp; 3035e96ac45SJed Brown char *tmp,*tmp1; 3045e96ac45SJed Brown ierr = PetscStrncmp(DebugTerminal,"screen",6,&cmp);CHKERRQ(ierr); 305a5ba6984SMatthew G. Knepley if (!cmp) {ierr = PetscStrncmp(DebugTerminal,"gnome-terminal",6,&cmp);CHKERRQ(ierr);} 3065e96ac45SJed Brown if (cmp) display[0] = 0; /* when using screen, we never pass -display */ 3075e96ac45SJed Brown args[j++] = tmp = DebugTerminal; 3085e96ac45SJed Brown if (display[0]) { 3095e96ac45SJed Brown args[j++] = "-display"; args[j++] = display; 3105e96ac45SJed Brown } 3115e96ac45SJed Brown while (*tmp) { 3125e96ac45SJed Brown ierr = PetscStrchr(tmp,' ',&tmp1);CHKERRQ(ierr); 3135e96ac45SJed Brown if (!tmp1) break; 3145e96ac45SJed Brown *tmp1 = 0; 3155e96ac45SJed Brown tmp = tmp1+1; 3165e96ac45SJed Brown args[j++] = tmp; 3175e96ac45SJed Brown } 3185e96ac45SJed Brown } 319b59f628eSBarry Smith args[j++] = PetscDebugger; 3205e96ac45SJed Brown jj = j; 32102c9f0b5SLisandro Dalcin args[j++] = program; args[j++] = pid; args[j++] = NULL; 3225e96ac45SJed Brown 323e5c89e4eSSatish Balay if (isidb) { 3245e96ac45SJed Brown j = jj; 3255e96ac45SJed Brown args[j++] = "-pid"; 3265e96ac45SJed Brown args[j++] = pid; 3275e96ac45SJed Brown args[j++] = "-gdb"; 3285e96ac45SJed Brown args[j++] = program; 32902c9f0b5SLisandro Dalcin args[j++] = NULL; 330e5c89e4eSSatish Balay } 3310e9bae81SBarry Smith if (islldb) { 3320e9bae81SBarry Smith j = jj; 3330e9bae81SBarry Smith args[j++] = "-p"; 3340e9bae81SBarry Smith args[j++] = pid; 33502c9f0b5SLisandro Dalcin args[j++] = NULL; 3360e9bae81SBarry Smith } 337e5c89e4eSSatish Balay if (isdbx) { 3385e96ac45SJed Brown j = jj; 3398d359177SBarry Smith #if defined(PETSC_USE_P_FOR_DEBUGGER) 3405e96ac45SJed Brown args[j++] = "-p"; 3415e96ac45SJed Brown args[j++] = pid; 3425e96ac45SJed Brown args[j++] = program; 343e5c89e4eSSatish Balay #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER) 3445e96ac45SJed Brown args[j++] = "-l"; 3455e96ac45SJed Brown args[j++] = "ALL"; 3465e96ac45SJed Brown args[j++] = "-P"; 3475e96ac45SJed Brown args[j++] = pid; 3485e96ac45SJed Brown args[j++] = program; 349e5c89e4eSSatish Balay #elif defined(PETSC_USE_A_FOR_DEBUGGER) 3505e96ac45SJed Brown args[j++] = "-a"; 3515e96ac45SJed Brown args[j++] = pid; 352e5c89e4eSSatish Balay #elif defined(PETSC_USE_PID_FOR_DEBUGGER) 3535e96ac45SJed Brown args[j++] = "-pid"; 3545e96ac45SJed Brown args[j++] = pid; 3555e96ac45SJed Brown args[j++] = program; 356493de400SSatish Balay #else 357493de400SSatish Balay args[j++] = program; 358493de400SSatish Balay args[j++] = pid; 3598d359177SBarry Smith #endif 36002c9f0b5SLisandro Dalcin args[j++] = NULL; 361e5c89e4eSSatish Balay } 3625e96ac45SJed Brown if (Xterm) { 363c5888dd7SBarry 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); 364c5888dd7SBarry Smith else printf("PETSC: Attaching %s to %s on pid %s on %s\n",PetscDebugger,program,pid,hostname); 365a297a907SKarl Rupp 3665e96ac45SJed Brown if (execvp(args[0],(char**)args) < 0) { 3675e96ac45SJed Brown perror("Unable to start debugger in xterm"); 3685e96ac45SJed Brown exit(0); 3695e96ac45SJed Brown } 3705e96ac45SJed Brown } else { 371c5888dd7SBarry Smith printf("PETSC: Attaching %s to %s of pid %s on %s\n",PetscDebugger,program,pid,hostname); 372e5c89e4eSSatish Balay if (execvp(args[0],(char**)args) < 0) { 373e5c89e4eSSatish Balay perror("Unable to start debugger"); 374e5c89e4eSSatish Balay exit(0); 375e5c89e4eSSatish Balay } 376e5c89e4eSSatish Balay } 377e5c89e4eSSatish Balay } 378e5c89e4eSSatish Balay } else { /* I am the child, continue with user code */ 379e5c89e4eSSatish Balay sleeptime = 10; /* default to sleep waiting for debugger */ 380c5929fdfSBarry Smith ierr = PetscOptionsGetReal(NULL,NULL,"-debugger_pause",&sleeptime,NULL);CHKERRQ(ierr); 381e5c89e4eSSatish Balay if (sleeptime < 0) sleeptime = -sleeptime; 382e5c89e4eSSatish Balay #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP) 383e5c89e4eSSatish Balay /* 384e5c89e4eSSatish Balay HP cannot attach process to sleeping debugger, hence count instead 385e5c89e4eSSatish Balay */ 386e5c89e4eSSatish Balay { 387e5c89e4eSSatish Balay PetscReal x = 1.0; 388e5c89e4eSSatish Balay int i =10000000; 389e5c89e4eSSatish Balay while (i--) x++; /* cannot attach to sleeper */ 390e5c89e4eSSatish Balay } 391e5c89e4eSSatish Balay #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY) 392e5c89e4eSSatish Balay /* 393e5c89e4eSSatish Balay IBM sleep may return at anytime, hence must see if there is more time to sleep 394e5c89e4eSSatish Balay */ 395e5c89e4eSSatish Balay { 396e5c89e4eSSatish Balay int left = sleeptime; 397a297a907SKarl Rupp while (left > 0) left = PetscSleep(left) - 1; 398e5c89e4eSSatish Balay } 399e5c89e4eSSatish Balay #else 400e5c89e4eSSatish Balay PetscSleep(sleeptime); 401e5c89e4eSSatish Balay #endif 402e5c89e4eSSatish Balay } 403e5c89e4eSSatish Balay #endif 404e5c89e4eSSatish Balay PetscFunctionReturn(0); 405e5c89e4eSSatish Balay } 406e5c89e4eSSatish Balay 407e5c89e4eSSatish Balay /*@C 408e5c89e4eSSatish Balay PetscAttachDebuggerErrorHandler - Error handler that attaches 409e5c89e4eSSatish Balay a debugger to a running process when an error is detected. 410e5c89e4eSSatish Balay This routine is useful for examining variables, etc. 411e5c89e4eSSatish Balay 412e5c89e4eSSatish Balay Not Collective 413e5c89e4eSSatish Balay 414e5c89e4eSSatish Balay Input Parameters: 415e32f2f54SBarry Smith + comm - communicator over which error occurred 416e32f2f54SBarry Smith . line - the line number of the error (indicated by __LINE__) 417e5c89e4eSSatish Balay . file - the file in which the error was detected (indicated by __FILE__) 418e5c89e4eSSatish Balay . message - an error text string, usually just printed to the screen 419e5c89e4eSSatish Balay . number - the generic error number 420668f157eSBarry Smith . p - PETSC_ERROR_INITIAL if error just detected, otherwise PETSC_ERROR_REPEAT 421e5c89e4eSSatish Balay - ctx - error handler context 422e5c89e4eSSatish Balay 423e5c89e4eSSatish Balay Options Database Keys: 424e5c89e4eSSatish Balay . -on_error_attach_debugger [noxterm,dbx,xxgdb,xdb,xldb,gdb] [-display name] - Activates 425e5c89e4eSSatish Balay debugger attachment 426e5c89e4eSSatish Balay 427e5c89e4eSSatish Balay Level: developer 428e5c89e4eSSatish Balay 429e5c89e4eSSatish Balay Notes: 430c4fb7a8fSRichard Tran Mills By default the GNU debugger, gdb, is used. Alternatives are cuda-gdb, lldb, dbx and 431e5c89e4eSSatish Balay xxgdb,xldb (on IBM rs6000), xdb (on HP-UX). 432e5c89e4eSSatish Balay 433e5c89e4eSSatish Balay Most users need not directly employ this routine and the other error 434e5c89e4eSSatish Balay handlers, but can instead use the simplified interface SETERR, which has 435e5c89e4eSSatish Balay the calling sequence 436e32f2f54SBarry Smith $ SETERRQ(PETSC_COMM_SELF,number,p,message) 437e5c89e4eSSatish Balay 438e5c89e4eSSatish Balay Notes for experienced users: 439e5c89e4eSSatish Balay Use PetscPushErrorHandler() to set the desired error handler. The 440e5c89e4eSSatish Balay currently available PETSc error handlers are 441e5c89e4eSSatish Balay $ PetscTraceBackErrorHandler() 442e5c89e4eSSatish Balay $ PetscAttachDebuggerErrorHandler() 443e5c89e4eSSatish Balay $ PetscAbortErrorHandler() 444e5c89e4eSSatish Balay or you may write your own. 445e5c89e4eSSatish Balay 446e5c89e4eSSatish Balay 447e5c89e4eSSatish Balay .seealso: PetscPushErrorHandler(), PetscTraceBackErrorHandler(), 448e5c89e4eSSatish Balay PetscAbortErrorHandler() 449e5c89e4eSSatish Balay @*/ 450efca3c55SSatish Balay PetscErrorCode PetscAttachDebuggerErrorHandler(MPI_Comm comm,int line,const char *fun,const char *file,PetscErrorCode num,PetscErrorType p,const char *mess,void *ctx) 451e5c89e4eSSatish Balay { 452e5c89e4eSSatish Balay PetscErrorCode ierr; 453e5c89e4eSSatish Balay 454e5c89e4eSSatish Balay PetscFunctionBegin; 455e5c89e4eSSatish Balay if (!fun) fun = "User provided function"; 456e5c89e4eSSatish Balay if (!mess) mess = " "; 457e5c89e4eSSatish Balay 458efca3c55SSatish Balay (*PetscErrorPrintf)("%s() line %d in %s %s\n",fun,line,file,mess); 459e5c89e4eSSatish Balay 460e5c89e4eSSatish Balay ierr = PetscAttachDebugger(); 461a297a907SKarl Rupp if (ierr) abort(); /* call abort because don't want to kill other MPI processes that may successfully attach to debugger */ 462e5c89e4eSSatish Balay PetscFunctionReturn(0); 463e5c89e4eSSatish Balay } 464e5c89e4eSSatish Balay 465e5c89e4eSSatish Balay /*@C 466e5c89e4eSSatish Balay PetscStopForDebugger - Prints a message to the screen indicating how to 467e5c89e4eSSatish Balay attach to the process with the debugger and then waits for the 468e5c89e4eSSatish Balay debugger to attach. 469e5c89e4eSSatish Balay 470e5c89e4eSSatish Balay Not Collective 471e5c89e4eSSatish Balay 4728d359177SBarry Smith Level: developer 473e5c89e4eSSatish Balay 47495452b02SPatrick Sanan Notes: 47595452b02SPatrick Sanan This is likely never needed since PetscAttachDebugger() is easier to use and seems to always work. 4768d359177SBarry Smith 47795452b02SPatrick Sanan Developer Notes: 47895452b02SPatrick Sanan Since this can be called by the error handler, should it be calling SETERRQ() and CHKERRQ()? 479f35f84d1SBarry Smith 480e5c89e4eSSatish Balay .seealso: PetscSetDebugger(), PetscAttachDebugger() 481e5c89e4eSSatish Balay @*/ 4827087cfbeSBarry Smith PetscErrorCode PetscStopForDebugger(void) 483e5c89e4eSSatish Balay { 484e5c89e4eSSatish Balay PetscErrorCode ierr; 485e5c89e4eSSatish Balay PetscInt sleeptime=0; 486e5c89e4eSSatish Balay #if !defined(PETSC_CANNOT_START_DEBUGGER) 48751ec2c11SGlenn Hammond int ppid; 488e5c89e4eSSatish Balay PetscMPIInt rank; 489e5c89e4eSSatish Balay char program[PETSC_MAX_PATH_LEN],hostname[256]; 4908d359177SBarry Smith PetscBool isdbx,isxldb,isxxgdb,isddd,iskdbg,isups,isxdb,islldb; 491e5c89e4eSSatish Balay #endif 492e5c89e4eSSatish Balay 493e5c89e4eSSatish Balay PetscFunctionBegin; 494e5c89e4eSSatish Balay #if defined(PETSC_CANNOT_START_DEBUGGER) 495e5c89e4eSSatish Balay (*PetscErrorPrintf)("System cannot start debugger; just continuing program\n"); 496e5c89e4eSSatish Balay #else 497e5c89e4eSSatish Balay ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank); 498f35f84d1SBarry Smith if (ierr) rank = 0; /* ignore error since this may be already in error handler */ 499589a23caSBarry Smith ierr = PetscGetHostName(hostname,sizeof(hostname)); 500e5c89e4eSSatish Balay if (ierr) { 501e5c89e4eSSatish Balay (*PetscErrorPrintf)("Cannot determine hostname; just continuing program\n"); 502e5c89e4eSSatish Balay PetscFunctionReturn(0); 503e5c89e4eSSatish Balay } 504e5c89e4eSSatish Balay 505589a23caSBarry Smith ierr = PetscGetProgramName(program,sizeof(program)); 506e5c89e4eSSatish Balay if (ierr) { 507e5c89e4eSSatish Balay (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n"); 508e5c89e4eSSatish Balay PetscFunctionReturn(0); 509e5c89e4eSSatish Balay } 510e5c89e4eSSatish Balay if (!program[0]) { 511e5c89e4eSSatish Balay (*PetscErrorPrintf)("Cannot determine program name; just continuing program\n"); 512e5c89e4eSSatish Balay PetscFunctionReturn(0); 513e5c89e4eSSatish Balay } 514e5c89e4eSSatish Balay 515e5c89e4eSSatish Balay ppid = getpid(); 516e5c89e4eSSatish Balay 517b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"xxgdb",&isxxgdb);CHKERRQ(ierr); 518b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"ddd",&isddd);CHKERRQ(ierr); 519b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"kdbg",&iskdbg);CHKERRQ(ierr); 520b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"ups",&isups);CHKERRQ(ierr); 521b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"xldb",&isxldb);CHKERRQ(ierr); 522b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"xdb",&isxdb);CHKERRQ(ierr); 523b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"dbx",&isdbx);CHKERRQ(ierr); 524b59f628eSBarry Smith ierr = PetscStrcmp(PetscDebugger,"lldb",&islldb);CHKERRQ(ierr); 525e5c89e4eSSatish Balay 526c5888dd7SBarry Smith if (isxxgdb || isups || isddd || iskdbg) printf("[%d]%s>>%s %s %d\n",rank,hostname,PetscDebugger,program,ppid); 527c5888dd7SBarry Smith else if (isxldb) printf("[%d]%s>>%s -a %d %s\n",rank,hostname,PetscDebugger,ppid,program); 528c5888dd7SBarry Smith else if (islldb) printf("[%d]%s>>%s -p %d\n",rank,hostname,PetscDebugger,ppid); 5298d359177SBarry Smith else if (isdbx) { 530e5c89e4eSSatish Balay #if defined(PETSC_USE_P_FOR_DEBUGGER) 531c5888dd7SBarry Smith printf("[%d]%s>>%s -p %d %s\n",rank,hostname,PetscDebugger,ppid,program); 532e5c89e4eSSatish Balay #elif defined(PETSC_USE_LARGEP_FOR_DEBUGGER) 533c5888dd7SBarry Smith printf("[%d]%s>>%s -l ALL -P %d %s\n",rank,hostname,PetscDebugger,ppid,program); 534e5c89e4eSSatish Balay #elif defined(PETSC_USE_A_FOR_DEBUGGER) 535c5888dd7SBarry Smith printf("[%d]%s>>%s -a %d\n",rank,hostname,PetscDebugger,ppid); 536e5c89e4eSSatish Balay #elif defined(PETSC_USE_PID_FOR_DEBUGGER) 537c5888dd7SBarry Smith printf("[%d]%s>>%s -pid %d %s\n",rank,hostname,PetscDebugger,ppid,program); 538e5c89e4eSSatish Balay #else 539c5888dd7SBarry Smith printf("[%d]%s>>%s %s %d\n",rank,hostname,PetscDebugger,program,ppid); 540e5c89e4eSSatish Balay #endif 5418d359177SBarry Smith } 542e5c89e4eSSatish Balay #endif /* PETSC_CANNOT_START_DEBUGGER */ 543e5c89e4eSSatish Balay 544f35f84d1SBarry Smith fflush(stdout); /* ignore error because may already be in error handler */ 545e5c89e4eSSatish Balay 546e5c89e4eSSatish Balay sleeptime = 25; /* default to sleep waiting for debugger */ 547c5929fdfSBarry Smith PetscOptionsGetInt(NULL,NULL,"-debugger_pause",&sleeptime,NULL); /* ignore error because may already be in error handler */ 548e5c89e4eSSatish Balay if (sleeptime < 0) sleeptime = -sleeptime; 549e5c89e4eSSatish Balay #if defined(PETSC_NEED_DEBUGGER_NO_SLEEP) 550e5c89e4eSSatish Balay /* 551e5c89e4eSSatish Balay HP cannot attach process to sleeping debugger, hence count instead 552e5c89e4eSSatish Balay */ 553e5c89e4eSSatish Balay { 554e5c89e4eSSatish Balay PetscReal x = 1.0; 555e5c89e4eSSatish Balay int i =10000000; 556e5c89e4eSSatish Balay while (i--) x++; /* cannot attach to sleeper */ 557e5c89e4eSSatish Balay } 558e5c89e4eSSatish Balay #elif defined(PETSC_HAVE_SLEEP_RETURNS_EARLY) 559e5c89e4eSSatish Balay /* 560e5c89e4eSSatish Balay IBM sleep may return at anytime, hence must see if there is more time to sleep 561e5c89e4eSSatish Balay */ 562e5c89e4eSSatish Balay { 563e5c89e4eSSatish Balay int left = sleeptime; 564a297a907SKarl Rupp while (left > 0) left = sleep(left) - 1; 565e5c89e4eSSatish Balay } 566e5c89e4eSSatish Balay #else 567e5c89e4eSSatish Balay PetscSleep(sleeptime); 568e5c89e4eSSatish Balay #endif 569e5c89e4eSSatish Balay PetscFunctionReturn(0); 570e5c89e4eSSatish Balay } 571