aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom de Vries <tdevries@suse.de>2024-10-25 12:48:18 +0200
committerTom de Vries <tdevries@suse.de>2024-10-25 12:48:18 +0200
commit3d17c8817216343179f64d1a682311a70774ccb4 (patch)
treec81ab73d91ad6457b85654f7523e6116961cf2f4
parentc33568d2c108478c25fe9959b5ce9d25b97efa6c (diff)
downloadgdb-3d17c8817216343179f64d1a682311a70774ccb4.zip
gdb-3d17c8817216343179f64d1a682311a70774ccb4.tar.gz
gdb-3d17c8817216343179f64d1a682311a70774ccb4.tar.bz2
[gdb] Handle bad alloc in gdb_rl_callback_read_char_wrapper_noexcept
Say we simulate a bad alloc in exceptions_state_mc_init: ... jmp_buf * exceptions_state_mc_init () { + { + static bool throw_bad_alloc = true; + if (throw_bad_alloc) + { + throw_bad_alloc = false; + + va_list dummy; + throw gdb_quit_bad_alloc (gdb_exception_quit ("bad alloc", dummy)); + } + } catchers.emplace_front (); return &catchers.front ().buf; } ... After starting gdb and typing "q", gdb terminates: ... $ gdb -q (gdb) terminate called after throwing an instance of 'gdb_quit_bad_alloc' what(): std::bad_alloc ... because the bad alloc (thrown in TRY_SJLJ) is caught by the noexcept on gdb_rl_callback_read_char_wrapper_noexcept: ... static struct gdb_exception gdb_rl_callback_read_char_wrapper_noexcept () noexcept { struct gdb_exception gdb_expt; /* C++ exceptions can't normally be thrown across readline (unless it is built with -fexceptions, but it won't by default on many ABIs). So we instead wrap the readline call with a sjlj-based TRY/CATCH, and rethrow the GDB exception once back in GDB. */ TRY_SJLJ ... Fix this by renaming gdb_rl_callback_read_char_wrapper_noexcept to gdb_rl_callback_read_char_wrapper_sjlj and calling it from a wrapper function that catches the bad alloc expection: ... 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); } } ... getting us instead: ... $ gdb -q (gdb) bad alloc (gdb) q ... Tested on aarch64-linux.
-rw-r--r--gdb/event-top.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/gdb/event-top.c b/gdb/event-top.c
index cdc7874..d3cf144 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)
{