|
|
| version 1.5, 2025/04/29 18:46:17 | version 1.8, 2025/04/30 20:03:09 |
|---|---|
| Line 24 | Line 24 |
| * along with FreeM. If not, see <https://www.gnu.org/licenses/>. | * along with FreeM. If not, see <https://www.gnu.org/licenses/>. |
| * | * |
| * $Log$ | * $Log$ |
| * 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 | * Revision 1.5 2025/04/29 18:46:17 snw |
| * Begin work on interactive debugger | * Begin work on interactive debugger |
| * | * |
| Line 98 void dbg_init (void) | Line 107 void dbg_init (void) |
| } | } |
| int debugger (void) | int debugger (int entry_mode, char *curcode) |
| { | { |
| #if defined(HAVE_LIBREADLINE) | #if defined(HAVE_LIBREADLINE) |
| static int first_entry = TRUE; | static int first_entry = TRUE; |
| static int stepmode = STEPMODE_NONE; | |
| char *dbg_buf; | char *dbg_buf; |
| char dbg_prompt[256]; | char dbg_prompt[256]; |
| HIST_ENTRY **dbg_hist; | HIST_ENTRY **dbg_hist; |
| int dbg_hist_idx; | int dbg_hist_idx; |
| HIST_ENTRY *dbg_hist_ent; | HIST_ENTRY *dbg_hist_ent; |
| char rouname_buf[256]; | char rouname_buf[256]; |
| char *savptr; | |
| char *dbg_cmd; | |
| int do_prompt = FALSE; | |
| register int i; | |
| set_io (UNIX); | set_io (UNIX); |
| Line 117 int debugger (void) | Line 132 int debugger (void) |
| printf ("\nEntering debug mode; M commands unavailable.\n"); | printf ("\nEntering debug mode; M commands unavailable.\n"); |
| printf ("Type 'exit' to return to direct mode; 'help' for help.\n\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) { | 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); | stcnv_m2c (rouname_buf); |
| snprintf (dbg_prompt, sizeof (dbg_prompt) - 1, "%s $STACK=%d [DEBUG]> ", rouname_buf, nstx); | 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); | dbg_buf = readline (dbg_prompt); |
| if (!dbg_buf) continue; | 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; | first_entry = TRUE; |
| stepmode = STEPMODE_NONE; | |
| printf ("\n\nExiting debug mode.\n\n"); | printf ("\n\nExiting debug mode.\n\n"); |
| set_io (MUMPS); | set_io (MUMPS); |
| return FALSE; | 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 { | else { |
| printf ("DEBUG: invalid command\r\n"); | printf ("DEBUG: invalid command\r\n"); |
| } | } |