aboutsummaryrefslogtreecommitdiff
path: root/gdb/event-top.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/event-top.c')
-rw-r--r--gdb/event-top.c121
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