diff options
Diffstat (limited to 'gdb/event-top.c')
-rw-r--r-- | gdb/event-top.c | 121 |
1 files changed, 112 insertions, 9 deletions
diff --git a/gdb/event-top.c b/gdb/event-top.c index b81970d..38a59ba 100644 --- a/gdb/event-top.c +++ b/gdb/event-top.c @@ -184,7 +184,7 @@ extern "C" void _rl_signal_handler (int); (sjlj-based) C++ exceptions. */ static struct gdb_exception -gdb_rl_callback_read_char_wrapper_noexcept () noexcept +gdb_rl_callback_read_char_wrapper_sjlj () { struct gdb_exception gdb_expt; @@ -229,6 +229,22 @@ gdb_rl_callback_read_char_wrapper_noexcept () noexcept return gdb_expt; } +/* Wrapper around gdb_rl_callback_read_char_wrapper_sjlj to ensure + noexcept. */ + +static struct gdb_exception +gdb_rl_callback_read_char_wrapper_noexcept () noexcept +{ + try + { + return gdb_rl_callback_read_char_wrapper_sjlj (); + } + catch (gdb_exception &ex) + { + return std::move (ex); + } +} + static void gdb_rl_callback_read_char_wrapper (gdb_client_data client_data) { @@ -371,6 +387,23 @@ gdb_rl_callback_handler_install (const char *prompt) therefore loses input. */ gdb_assert (!callback_handler_installed); +#ifdef RL_STATE_EOF + /* Some versions of readline contain a bug where the rl_eof_found flag + would not be reset back to 0 in rl_initialize, despite the + RL_STATE_EOF flag being cleared in this function. + + The consequence of this mistake is that readline will appear to get + stuck in the EOF state, and will emit an extra '\n' character each + time an input line is completed. + + Work around this by clearing the EOF state now ourselves. */ + if (RL_ISSTATE (RL_STATE_EOF)) + { + RL_UNSETSTATE (RL_STATE_EOF); + rl_eof_found = 0; + } +#endif /* RL_STATE_EOF */ + rl_callback_handler_install (prompt, gdb_rl_callback_handler); callback_handler_installed = true; } @@ -892,9 +925,54 @@ unblock_signal (int sig) return false; } +/* Signal safe language specific strings. */ + +#ifdef GDB_PRINT_INTERNAL_BACKTRACE +static const char *str_fatal_signal; +static const char *str_sigsegv; +#ifdef SIGFPE +static const char *str_sigfpe; +#endif +#ifdef SIGBUS +static const char *str_sigbus; +#endif +#ifdef SIGABRT +static const char *str_sigabrt; +#endif +static const char *str_unknown_signal; +static const char *str_fatal_error_detected_gdb_will_now_terminate; +static const char *str_this_is_a_bug; +static const char *str_for_instructions_see; + +/* Initialize language specific strings. */ + +static void +init_str_handle_fatal_signal () +{ + str_fatal_signal = _("Fatal signal: "); + str_sigsegv = strsignal (SIGSEGV); +#ifdef SIGFPE + str_sigfpe = strsignal (SIGFPE); +#endif +#ifdef SIGBUS + str_sigbus = strsignal (SIGBUS); +#endif +#ifdef SIGABRT + str_sigabrt = strsignal (SIGABRT); +#endif + str_unknown_signal = _("Unknown signal"); + str_fatal_error_detected_gdb_will_now_terminate = + _("A fatal error internal to GDB has been detected, " + "further\ndebugging is not possible. GDB will now " + "terminate.\n\n"); + str_this_is_a_bug = _("This is a bug, please report it."); + str_for_instructions_see = _(" For instructions, see:\n"); +} +#endif + /* Called to handle fatal signals. SIG is the signal number. */ -static void ATTRIBUTE_NORETURN +[[noreturn]] static void handle_fatal_signal (int sig) { #ifdef TUI @@ -910,19 +988,40 @@ handle_fatal_signal (int sig) if (bt_on_fatal_signal) { sig_write ("\n\n"); - sig_write (_("Fatal signal: ")); - sig_write (strsignal (sig)); + sig_write (str_fatal_signal); + switch (sig) + { + case SIGSEGV: + sig_write (str_sigsegv); + break; +#ifdef SIGFPE + case SIGFPE: + sig_write (str_sigfpe); + break; +#endif +#ifdef SIGBUS + case SIGBUS: + sig_write (str_sigbus); + break; +#endif +#ifdef SIGABRT + case SIGABRT: + sig_write (str_sigabrt); + break; +#endif + default: + sig_write (str_unknown_signal); + break; + } sig_write ("\n"); gdb_internal_backtrace (); - sig_write (_("A fatal error internal to GDB has been detected, " - "further\ndebugging is not possible. GDB will now " - "terminate.\n\n")); - sig_write (_("This is a bug, please report it.")); + sig_write (str_fatal_error_detected_gdb_will_now_terminate); + sig_write (str_this_is_a_bug); if (REPORT_BUGS_TO[0] != '\0') { - sig_write (_(" For instructions, see:\n")); + sig_write (str_for_instructions_see); sig_write (REPORT_BUGS_TO); sig_write ("."); } @@ -1050,6 +1149,10 @@ gdb_init_signals (void) create_async_signal_handler (async_sigtstp_handler, NULL, "sigtstp"); #endif +#ifdef GDB_PRINT_INTERNAL_BACKTRACE + init_str_handle_fatal_signal (); +#endif + #ifdef SIGFPE signal (SIGFPE, handle_fatal_signal); #endif |