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