From 474f84244dd11816d6c23fa7fdbec4a3df754a46 Mon Sep 17 00:00:00 2001 From: "B. Scott Michel" Date: Thu, 20 Mar 2025 16:29:35 -1000 Subject: [PATCH] CONSOLE: Separate debug character from signal Add the "DBGSIGNAL", "DBGSIG" options to enable sending the interrupt to the user's debugger, which is presumably gdb. Separates setting the debugging interrupt character from the action so that it is possible to turn debugger interrupts on and off: set console dbgint=1f dbgsignal set console nodbgsignal Previously, this feature was only available if the compiler did not define __OPTIMIZE__, which precludes optimized debugging code, i.e., compiling with "-O2 -g". --- sim_console.c | 128 ++++++++++++++++++++++++++++++++++++-------------- sim_console.h | 3 ++ 2 files changed, 96 insertions(+), 35 deletions(-) diff --git a/sim_console.c b/sim_console.c index 9421571b..990d10f6 100644 --- a/sim_console.c +++ b/sim_console.c @@ -148,7 +148,9 @@ int setenv(const char *envname, const char *envval, int overwrite); /* Forward Declarations of Platform specific routines */ static t_stat sim_os_poll_kbd (void); +#if defined(SIM_ASYNCH_IO) && defined(SIM_ASYNCH_MUX) static t_bool sim_os_poll_kbd_ready (int ms_timeout); +#endif static t_stat sim_os_putchar (int32 out); static t_stat sim_os_ttinit (void); static t_stat sim_os_ttrun (void); @@ -178,6 +180,7 @@ static t_stat sim_set_delay (int32 flag, CONST char *cptr); int32 sim_int_char = 005; /* interrupt character */ int32 sim_dbg_int_char = 0; /* SIGINT char under debugger */ +int32 sim_dbg_signal = 0; /* Enable SIGINT to debugger */ static t_bool sigint_message_issued = FALSE; int32 sim_brk_char = 000; /* break character */ int32 sim_tt_pchar = 0x00002780; @@ -317,7 +320,6 @@ static CTAB set_con_tab[] = { { "WRU", &sim_set_kmap, KMAP_WRU | KMAP_NZ }, { "BRK", &sim_set_kmap, KMAP_BRK }, { "DEL", &sim_set_kmap, KMAP_DEL | KMAP_NZ }, - { "DBGINT", &sim_set_kmap, KMAP_DBGINT | KMAP_NZ }, { "PCHAR", &sim_set_pchar, 0 }, { "SPEED", &sim_set_cons_speed, 0 }, { "TELNET", &sim_set_telnet, 0 }, @@ -334,6 +336,11 @@ static CTAB set_con_tab[] = { { "DELAY", &sim_set_delay, 0 }, { "RESPONSE", &sim_set_response, 1 | CMD_WANTSTR }, { "NORESPONSE", &sim_set_response, 0 }, + { "DBGINT", &sim_set_kmap, KMAP_DBGINT | KMAP_NZ }, + { "DBGSIG", &sim_set_dbgsignal, 0 }, + { "DBGSIGNAL", &sim_set_dbgsignal, 0 }, + { "NODBGSIG", &sim_reset_dbgsignal, 0 }, + { "NODBGSIGNAL", &sim_reset_dbgsignal, 0 }, { NULL, NULL, 0 } }; @@ -352,7 +359,7 @@ static SHTAB show_con_tab[] = { { "WRU", &sim_show_kmap, KMAP_WRU }, { "BRK", &sim_show_kmap, KMAP_BRK }, { "DEL", &sim_show_kmap, KMAP_DEL }, -#if (defined(__GNUC__) && !defined(__OPTIMIZE__) && !defined(_WIN32)) /* Debug build? */ +#if !defined(_WIN32) && !defined(_WIN64) && !defined(VMS) { "DBGINT", &sim_show_kmap, KMAP_DBGINT }, #endif { "PCHAR", &sim_show_pchar, 0 }, @@ -366,6 +373,7 @@ static SHTAB show_con_tab[] = { { "INPUT", &sim_show_cons_send_input, 0 }, { "RESPONSE", &sim_show_cons_send_input, -1 }, { "DELAY", &sim_show_cons_expect, -1 }, + { "DBGSIGNAL", &sim_show_dbgsignal, 0 }, { NULL, NULL, 0 } }; @@ -2192,7 +2200,7 @@ else if (isprint(kmap_char&0xFF)) fprintf (st, " = '%c'\n", kmap_char&0xFF); else - if (kmap_char <= 26) + if (kmap_char <= 32) fprintf (st, " = ^%c\n", '@' + (kmap_char&0xFF)); else if (kmap_char == 28) @@ -2951,6 +2959,48 @@ fprintf (st, "Console Send processing:\n"); return sim_show_send_input (st, &sim_con_send); } +/* Enable console signal to debugger (for GNU C, Clang and not on Windows. */ +t_stat sim_set_dbgsignal (int32 flag, CONST char *cptr) +{ +#if !defined(_WIN32) && !defined(_WIN64) && !defined(VMS) +if (cptr != NULL && *cptr != '\0') + return SCPE_2FARG; + +sim_dbg_signal = TRUE; /* Enable SIGINT to debugger */ +return sim_messagef(SCPE_OK, "SIGINT to debugger enabled.\n"); +#else +return sim_messagef(SCPE_NOFNC, "Debugger interrupt not supported on this platform.\n"); +#endif +} + +/* Turn off debugger signal */ +t_stat sim_reset_dbgsignal (int32 flag, CONST char *cptr) +{ +#if !defined(_WIN32) && !defined(_WIN64) && !defined(VMS) +if (cptr != NULL && *cptr != '\0') /* too many arguments? */ + return SCPE_2MARG; + +sim_dbg_signal = FALSE; /* Disable SIGINT to debugger */ +return sim_messagef(SCPE_OK, "SIGINT to debugger is disabled.\n"); +#else +return sim_messagef(SCPE_NOFNC, "Debugger interrupt not supported on this platform.\n"); +#endif +} + +t_stat sim_show_dbgsignal (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONST char *cptr) +{ +#if !defined(_WIN32) && !defined(_WIN64) && !defined(VMS) +if (cptr != NULL && *cptr != '\0') /* too many arguments? */ + return SCPE_2MARG; + +fprintf(st, "%s interrupts to the debugger.\n", sim_dbg_signal ? "Delivering" : "Not delivering"); +#else +fprintf(st, "Debugger interrupt not supported.\n"); +#endif + +return SCPE_OK; +} + /* Poll for character */ t_stat sim_poll_kbd (void) @@ -3791,26 +3841,30 @@ static t_stat sim_os_ttrun (void) { sim_debug (DBG_TRC, &sim_con_telnet, "sim_os_ttrun() - BSDTTY\n"); -#if (defined(__GNUC__) && !defined(__OPTIMIZE__)) /* Debug build? */ -if (sim_dbg_int_char == 0) - sim_dbg_int_char = sim_int_char + 1; -runtchars.t_intrc = sim_dbg_int_char; /* let debugger get SIGINT with next highest char */ -if (!sigint_message_issued) { - char sigint_name[8]; +if (sim_dbg_signal) { + if (sim_dbg_int_char == 0) + sim_dbg_int_char = sim_int_char + 1; /* Set a reasonable default */ + runtchars.t_intrc = sim_dbg_int_char; /* let debugger get SIGINT with next highest char */ - if (isprint(sim_dbg_int_char&0xFF)) - sprintf(sigint_name, "'%c'", sim_dbg_int_char&0xFF); - else - if (sim_dbg_int_char <= 26) - sprintf(sigint_name, "^%c", '@' + (sim_dbg_int_char&0xFF)); + if (!sigint_message_issued) { + char sigint_name[8]; + + if (isprint(sim_dbg_int_char&0xFF)) + sprintf(sigint_name, "'%c'", sim_dbg_int_char&0xFF); else - sprintf(sigint_name, "'\\%03o'", sim_dbg_int_char&0xFF); - sigint_message_issued = TRUE; - sim_messagef (SCPE_OK, "SIGINT will be delivered to your debugger when the %s character is entered\n", sigint_name); + if (sim_dbg_int_char <= 32) + sprintf(sigint_name, "'^%c'", '@' + (sim_dbg_int_char&0xFF)); + else + sprintf(sigint_name, "'\\%03o'", sim_dbg_int_char&0xFF); + + sim_messagef (SCPE_OK, "SIGINT will be delivered to your debugger when the %s character is entered\n", + sigint_name); + + sigint_message_issued = TRUE; + } } -#else -runtchars.t_intrc = sim_int_char; /* in case changed */ -#endif +else + runtchars.t_intrc = sim_int_char; /* in case changed */ fcntl (0, F_SETFL, runfl); /* non-block mode */ if (ioctl (0, TIOCSETP, &runtty) < 0) return SCPE_TTIERR; @@ -3979,24 +4033,28 @@ runtty.c_cc[VINTR] = 0; /* OS X doesn't deliver #else runtty.c_cc[VINTR] = sim_int_char; /* in case changed */ #endif -#if (defined(__GNUC__) && !defined(__OPTIMIZE__)) /* Debug build? */ -if (sim_dbg_int_char == 0) - sim_dbg_int_char = sim_int_char + 1; -runtty.c_cc[VINTR] = sim_dbg_int_char; /* let debugger get SIGINT with next highest char */ -if (!sigint_message_issued) { - char sigint_name[8]; +if (sim_dbg_signal) { + if (sim_dbg_int_char == 0) + sim_dbg_int_char = sim_int_char + 1; /* Set a reasonable default */ + runtty.c_cc[VINTR] = sim_dbg_int_char; /* let debugger get SIGINT with next highest char */ - if (isprint(sim_dbg_int_char&0xFF)) - sprintf(sigint_name, "'%c'", sim_dbg_int_char&0xFF); - else - if (sim_dbg_int_char <= 26) - sprintf(sigint_name, "^%c", '@' + (sim_dbg_int_char&0xFF)); + if (!sigint_message_issued) { + char sigint_name[8]; + + if (isprint(sim_dbg_int_char&0xFF)) + sprintf(sigint_name, "'%c'", sim_dbg_int_char&0xFF); else - sprintf(sigint_name, "'\\%03o'", sim_dbg_int_char&0xFF); - sigint_message_issued = TRUE; - sim_messagef (SCPE_OK, "SIGINT will be delivered to your debugger when the %s character is entered\n", sigint_name); + if (sim_dbg_int_char <= 32) + sprintf(sigint_name, "'^%c'", '@' + (sim_dbg_int_char&0xFF)); + else + sprintf(sigint_name, "'\\%03o'", sim_dbg_int_char&0xFF); + + sim_messagef (SCPE_OK, "SIGINT will be delivered to your debugger when the %s character is entered\n", + sigint_name); + + sigint_message_issued = TRUE; + } } -#endif if (tcsetattr (fileno(stdin), TCSETATTR_ACTION, &runtty) < 0) return SCPE_TTIERR; sim_os_set_thread_priority (PRIORITY_BELOW_NORMAL); /* try to lower pri */ diff --git a/sim_console.h b/sim_console.h index e044bf35..f413257d 100644 --- a/sim_console.h +++ b/sim_console.h @@ -94,6 +94,8 @@ t_stat sim_set_cons_expect (int32 flg, CONST char *cptr); t_stat sim_set_cons_noexpect (int32 flg, CONST char *cptr); t_stat sim_set_pchar (int32 flag, CONST char *cptr); t_stat sim_set_cons_speed (int32 flag, CONST char *cptr); +t_stat sim_set_dbgsignal (int32 flag, CONST char *cptr); +t_stat sim_reset_dbgsignal (int32 flag, CONST char *cptr); t_stat sim_show_console (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONST char *cptr); t_stat sim_show_remote_console (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONST char *cptr); t_stat sim_show_kmap (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONST char *cptr); @@ -106,6 +108,7 @@ t_stat sim_show_cons_buff (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONST t_stat sim_show_cons_log (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONST char *cptr); t_stat sim_show_cons_debug (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONST char *cptr); t_stat sim_show_cons_expect (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONST char *cptr); +t_stat sim_show_dbgsignal (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, CONST char *cptr); t_stat sim_check_console (int32 sec); t_stat sim_open_logfile (const char *filename, t_bool binary, FILE **pf, FILEREF **pref); t_stat sim_close_logfile (FILEREF **pref);