|
|
| version 1.10, 2025/05/01 04:45:15 | version 1.11, 2025/05/01 17:02:30 |
|---|---|
| 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.11 2025/05/01 17:02:30 snw | |
| * Further debugging improvements | |
| * | |
| * Revision 1.10 2025/05/01 04:45:15 snw | * Revision 1.10 2025/05/01 04:45:15 snw |
| * Improve backtraces | * Improve backtraces |
| * | * |
| Line 113 void dbg_init (void) | Line 116 void dbg_init (void) |
| } | } |
| int debugger (int entry_mode, char *curcode) | int debugger (int entry_mode, char *entryref) |
| { | { |
| #if defined(HAVE_LIBREADLINE) | #if defined(HAVE_LIBREADLINE) |
| Line 122 int debugger (int entry_mode, char *curc | Line 125 int debugger (int entry_mode, char *curc |
| char *dbg_buf; | char *dbg_buf; |
| char dbg_prompt[256]; | char dbg_prompt[256]; |
| int dbg_argc; | |
| 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 *savptr; |
| char *dbg_cmd; | char *dbg_cmd; |
| char *dbarg; | |
| int do_prompt = FALSE; | int do_prompt = FALSE; |
| char cur_code[512]; | |
| char tbuf[512]; | |
| char tbuf2[512]; | |
| register int i; | register int i; |
| register int j; | register int j; |
| Line 183 int debugger (int entry_mode, char *curc | Line 191 int debugger (int entry_mode, char *curc |
| stcpy (rouname_buf, rou_name); | stcpy (rouname_buf, rou_name); |
| } | } |
| else { | else { |
| char tbuf[256]; | |
| getraddress (tbuf, nstx); | getraddress (tbuf, nstx); |
| stcpy (rouname_buf, &(tbuf[3])); | 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); | if (stepmode != STEPMODE_NONE) { |
| getraddress (tbuf, nstx); | |
| stcnv_m2c (tbuf); | |
| strcpy (tbuf2, &(tbuf[3])); | |
| routine_get_line (tbuf2, cur_code); | |
| if ((stepmode == STEPMODE_LINE) || (stepmode == STEPMODE_CMD)) { | printf ("%s\n", cur_code); |
| char codbuf[512]; | |
| stcpy (codbuf, curcode); | |
| stcnv_m2c (codbuf); | |
| printf ("%s\n", codbuf); | |
| } | } |
| dbg_buf = readline (dbg_prompt); | |
| snprintf (dbg_prompt, sizeof (dbg_prompt) - 1, "%s $STACK=%d [DEBUG]> ", rouname_buf, nstx); | |
| dbg_buf = readline (dbg_prompt); | |
| if (!dbg_buf) continue; | if (!dbg_buf) continue; |
| if (strlen (dbg_buf) < 1) continue; | |
| dbg_argc = 1; | |
| for (i = 0; i < strlen (dbg_buf); i++) { | |
| if (dbg_buf[i] == ' ') dbg_argc++; | |
| } | |
| dbarg = dbg_buf; | |
| savptr = dbg_buf; | savptr = dbg_buf; |
| dbg_cmd = strtok_r (dbg_buf, " ", &savptr); | dbg_cmd = strtok_r (dbg_buf, " ", &savptr); |
| dbarg += strlen (dbg_cmd) + 1; | |
| if ((strcmp (dbg_cmd, "exit") == 0) || (strcmp (dbg_cmd, "quit") == 0)) { | if ((strcmp (dbg_cmd, "exit") == 0) || (strcmp (dbg_cmd, "quit") == 0)) { |
| first_entry = TRUE; | first_entry = TRUE; |
| stepmode = STEPMODE_NONE; | stepmode = STEPMODE_NONE; |
| Line 213 int debugger (int entry_mode, char *curc | Line 229 int debugger (int entry_mode, char *curc |
| set_io (MUMPS); | set_io (MUMPS); |
| return FALSE; | return FALSE; |
| } | } |
| else if ((strcmp (dbg_cmd, "examine") == 0) || (strcmp (dbg_cmd, "e") == 0)) { | |
| char *glvn; | |
| char key[STRLEN]; | |
| char res[STRLEN]; | |
| if (dbg_argc < 2) { | |
| printf ("debug: syntax error\n"); | |
| } | |
| else { | |
| glvn = dbarg; | |
| name_to_key (key, glvn, STRLEN - 1); | |
| if (key[0] != '^') { | |
| symtab (get_sym, key, res); | |
| } | |
| else { | |
| if (key[1] != '$') { | |
| global (get_sym, key, res); | |
| } | |
| else { | |
| ssvn (get_sym, key, res); | |
| } | |
| } | |
| if (merr () != OK) { | |
| if (merr () == M6) { | |
| printf ("examine: local variable %s is not defined\n", glvn); | |
| merr_clear (); | |
| } | |
| else if (merr () == M7) { | |
| printf ("examine: global variable %s is not defined\n", glvn); | |
| merr_clear (); | |
| } | |
| else { | |
| printf ("examine: error retrieving %s\n", glvn); | |
| merr_clear (); | |
| } | |
| } | |
| else { | |
| stcnv_m2c (res); | |
| printf ("%s=\"%s\"\n", glvn, res); | |
| } | |
| } | |
| } | |
| else if ((strcmp (dbg_cmd, "trace") == 0) || (strcmp (dbg_cmd, "t") == 0)) { | |
| if (trace_mode == 0) { | |
| trace_mode = 1; | |
| printf ("debug: trace on\n"); | |
| } | |
| else { | |
| trace_mode = 0; | |
| printf ("debug: trace off\n"); | |
| } | |
| ssvn_job_update (); | |
| } | |
| else if ((strcmp (dbg_cmd, "step") == 0) || (strcmp (dbg_cmd, "s") == 0)) { | else if ((strcmp (dbg_cmd, "step") == 0) || (strcmp (dbg_cmd, "s") == 0)) { |
| stepmode = STEPMODE_CMD; | stepmode = STEPMODE_CMD; |
| return TRUE; | return TRUE; |
| Line 343 void dbg_dump_watchlist (void) | Line 414 void dbg_dump_watchlist (void) |
| register int i; | register int i; |
| for (i = 0; i < MAXWATCH; i++) { | for (i = 0; i < MAXWATCH; i++) { |
| if (dbg_watchlist[i].firect) { | if (dbg_watchlist[i].firect) { |
| dbg_dump_watch (dbg_watchlist[i].varnam); | dbg_dump_watch (dbg_watchlist[i].varnam); |
| } | } |
| } | } |
| dbg_pending_watches = 0; | dbg_pending_watches = 0; |
| Line 456 char *dbg_get_watch_name (char *varnam) | Line 527 char *dbg_get_watch_name (char *varnam) |
| void dbg_fire_watch (char *varnam) { | void dbg_fire_watch (char *varnam) { |
| dbg_watch *w; | dbg_watch *w; |
| if ((w = dbg_find_watch (varnam)) == NULL) { | if ((w = dbg_find_watch (varnam)) == NULL) { |
| return; | return; |
| } | } |
| w->chgct++; | w->chgct++; |
| w->firect++; | w->firect++; |
| dbg_pending_watches++; | dbg_pending_watches++; |
| } | } |