--- freem/src/mdebug.c 2025/04/29 18:46:17 1.5 +++ freem/src/mdebug.c 2025/04/30 20:03:09 1.8 @@ -1,5 +1,5 @@ /* - * $Id: mdebug.c,v 1.5 2025/04/29 18:46:17 snw Exp $ + * $Id: mdebug.c,v 1.8 2025/04/30 20:03:09 snw Exp $ * debugger enhancements * * @@ -24,6 +24,15 @@ * along with FreeM. If not, see . * * $Log: mdebug.c,v $ + * Revision 1.8 2025/04/30 20:03:09 snw + * Work on entryref parser + * + * Revision 1.7 2025/04/30 17:19:16 snw + * Improve backtraces in debugger + * + * Revision 1.6 2025/04/30 14:41:03 snw + * Further debugger work + * * Revision 1.5 2025/04/29 18:46:17 snw * Begin work on interactive debugger * @@ -98,17 +107,23 @@ void dbg_init (void) } -int debugger (void) +int debugger (int entry_mode, char *curcode) { #if defined(HAVE_LIBREADLINE) static int first_entry = TRUE; + static int stepmode = STEPMODE_NONE; + char *dbg_buf; char dbg_prompt[256]; HIST_ENTRY **dbg_hist; int dbg_hist_idx; HIST_ENTRY *dbg_hist_ent; char rouname_buf[256]; + char *savptr; + char *dbg_cmd; + int do_prompt = FALSE; + register int i; set_io (UNIX); @@ -117,24 +132,117 @@ int debugger (void) printf ("\nEntering debug mode; M commands unavailable.\n"); printf ("Type 'exit' to return to direct mode; 'help' for help.\n\n"); + + do_prompt = TRUE; + } + else { + switch (entry_mode) { + + case DEBENTRY_CMD: + if (stepmode == STEPMODE_CMD) { + do_prompt = TRUE; + } + else { + do_prompt = FALSE; + } + + break; + + case DEBENTRY_LINE: + if (stepmode == STEPMODE_CMD || stepmode == STEPMODE_LINE) { + do_prompt = TRUE; + } + else { + do_prompt = FALSE; + } + + break; + + case DEBENTRY_BREAKPOINT: + do_prompt = TRUE; + break; + + case DEBENTRY_SIGINT: + break; + } } + + if (!do_prompt) return TRUE; + while (1) { - stcpy (rouname_buf, rou_name); + + if (nstx == 0) { + stcpy (rouname_buf, rou_name); + } + else { + char tbuf[256]; + + getraddress (tbuf, nstx); + stcpy (rouname_buf, &(tbuf[3])); + } stcnv_m2c (rouname_buf); snprintf (dbg_prompt, sizeof (dbg_prompt) - 1, "%s $STACK=%d [DEBUG]> ", rouname_buf, nstx); + if ((stepmode == STEPMODE_LINE) || (stepmode == STEPMODE_CMD)) { + char codbuf[512]; + stcpy (codbuf, curcode); + stcnv_m2c (codbuf); + + printf ("%s\n", codbuf); + } dbg_buf = readline (dbg_prompt); if (!dbg_buf) continue; - if (strcmp (dbg_buf, "exit") == 0) { + savptr = dbg_buf; + dbg_cmd = strtok_r (dbg_buf, " ", &savptr); + + if ((strcmp (dbg_cmd, "exit") == 0) || (strcmp (dbg_cmd, "quit") == 0)) { first_entry = TRUE; + stepmode = STEPMODE_NONE; printf ("\n\nExiting debug mode.\n\n"); set_io (MUMPS); return FALSE; } + else if ((strcmp (dbg_cmd, "step") == 0) || (strcmp (dbg_cmd, "s") == 0)) { + stepmode = STEPMODE_CMD; + return TRUE; + } + else if ((strcmp (dbg_cmd, "next") == 0) || (strcmp (dbg_cmd, "n") == 0)) { + stepmode = STEPMODE_LINE; + return TRUE; + } + else if ((strcmp (dbg_cmd, "continue") == 0) || (strcmp (dbg_cmd, "cont") == 0) || (strcmp(dbg_cmd, "c") == 0)) { + stepmode = STEPMODE_CONT; + return TRUE; + } + else if ((strcmp (dbg_cmd, "backtrace") == 0) || (strcmp (dbg_cmd, "bt") == 0)) { + char tmpbuf[256]; + char ecbuf[256]; + char lref[256]; + char bt_mcode[256]; + + printf ("%-10s%s\n", "$STACK", "ENTRY"); + printf ("%-10s%s\n", "======", "====="); + + + for (i = 1; i <= nstx; i++) getraddress (callerr[i], i); + for (i = nstx; i > 0; i--) { + + stcpy (tmpbuf, callerr[i]); + stcnv_m2c (tmpbuf); + + printf ("%-10d%s\n", i, &(tmpbuf[3])); + stcpy (lref, &(tmpbuf[3])); + stcnv_m2c (lref); + if (routine_get_line (lref, bt_mcode) != NULL) { + stcnv_m2c (bt_mcode); + printf ("\t%s\n", bt_mcode); + } + } + } else { printf ("DEBUG: invalid command\r\n"); }