diff options
author | Tom de Vries <tdevries@suse.de> | 2024-10-25 12:48:18 +0200 |
---|---|---|
committer | Tom de Vries <tdevries@suse.de> | 2024-10-25 12:48:18 +0200 |
commit | 3d17c8817216343179f64d1a682311a70774ccb4 (patch) | |
tree | c81ab73d91ad6457b85654f7523e6116961cf2f4 | |
parent | c33568d2c108478c25fe9959b5ce9d25b97efa6c (diff) | |
download | gdb-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.c | 18 |
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) { |