[PATCH] [gdb] Handle ^C during disassembly

Tom de Vries tdevries@suse.de
Fri Aug 9 07:26:44 GMT 2024


On 8/8/24 23:58, Tom de Vries wrote:
> On 8/8/24 19:21, Andrew Burgess wrote:
>> Tom de Vries <tdevries@suse.de> writes:
>>
>>> In PR gdb/32025, a fatal error was reported when sending a SIGINT to 
>>> gdb while
>>> disassembling.
>>>
>>> I managed to reproduce this on aarch64-linux in a Leap 15.5 container 
>>> using
>>> this trigger patch:
>>> ...
>>>   gdb_disassembler_memory_reader::dis_asm_read_memory
>>>     (bfd_vma memaddr, gdb_byte *myaddr, unsigned int len,
>>>      struct disassemble_info *info) noexcept
>>>   {
>>> +  set_quit_flag ();
>>>     return target_read_code (memaddr, myaddr, len);
>>>   }
>>> ...
>>> and a simple gdb command line calling the disassemble command:
>>> ...
>>> $ gdb -q -batch a.out -ex "disassemble main"
>>> ...
>>>
>>> The following scenario leads to the fatal error:
>>> - the disassemble command is executed,
>>> - set_quit_flag is called in
>>>    gdb_disassembler_memory_reader::dis_asm_read_memory, pretending 
>>> that a
>>>    user pressed ^C,
>>> - target_read_code calls QUIT, which throws a
>>>    gdb_exception_quit,
>>> - the exception propagation mechanism reaches c code in libopcodes 
>>> and a fatal
>>>    error triggers because the c code is not compiled with -fexception.
>>>

I also managed to reproduce this on x86_64-linux, which proves that the 
bit about -fexception is incorrect.

The error triggers because 
gdb_disassembler_memory_reader::dis_asm_read_memory has noexcept.

Knowing now that this reproduces on more than one architecture, I'd like 
to backport this patch to gdb-15-branch.

WDYT?

Thanks
- Tom


>>> Fix this by:
>>> - wrapping the body of 
>>> gdb_disassembler_memory_reader::dis_asm_read_memory in
>>>    catch_exceptions (which consequently needs moving to a header 
>>> file), and
>>> - reraising the caught exception in default_print_insn using QUIT.
>>>
>>> Tested on aarch64-linux.
>>
>> Thanks for fixing this.
>>
>> I haven't looked at the possible test yet.  I think having tests would
>> be nice, but also those could potentially come later.  Anyway, I'll
>> leave this:
>>
>> Approved-By: Andrew Burgess <aburgess@redhat.com>
>>
>> You can merge now if you want, or work on the tests first.
>>
> 
> Hi Andrew,
> 
> thanks for the reviews, I've chosen to merge both patches.
> 
> Thanks,
> - Tom
> 
>>
>>>
>>> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32025
>>> ---
>>>   gdb/arch-utils.c |  7 ++++++-
>>>   gdb/disasm.c     |  7 ++++++-
>>>   gdb/event-top.h  | 25 +++++++++++++++++++++++++
>>>   gdb/gdb_bfd.c    | 23 -----------------------
>>>   4 files changed, 37 insertions(+), 25 deletions(-)
>>>
>>> diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c
>>> index fb5634d5fa0..785940da70c 100644
>>> --- a/gdb/arch-utils.c
>>> +++ b/gdb/arch-utils.c
>>> @@ -37,6 +37,7 @@
>>>   #include "auxv.h"
>>>   #include "observable.h"
>>>   #include "solib-target.h"
>>> +#include "event-top.h"
>>>   #include "gdbsupport/version.h"
>>> @@ -1040,7 +1041,11 @@ default_print_insn (bfd_vma memaddr, 
>>> disassemble_info *info)
>>>                    info->mach, current_program_space->exec_bfd ());
>>>     gdb_assert (disassemble_fn != NULL);
>>> -  return (*disassemble_fn) (memaddr, info);
>>> +  int res = (*disassemble_fn) (memaddr, info);
>>> +
>>> +  QUIT;
>>> +
>>> +  return res;
>>>   }
>>>   /* See arch-utils.h.  */
>>> diff --git a/gdb/disasm.c b/gdb/disasm.c
>>> index 16736e54997..7209cfc227b 100644
>>> --- a/gdb/disasm.c
>>> +++ b/gdb/disasm.c
>>> @@ -197,7 +197,12 @@ gdb_disassembler_memory_reader::dis_asm_read_memory
>>>     (bfd_vma memaddr, gdb_byte *myaddr, unsigned int len,
>>>      struct disassemble_info *info) noexcept
>>>   {
>>> -  return target_read_code (memaddr, myaddr, len);
>>> +  auto res = catch_exceptions<int, -1> ([&]
>>> +    {
>>> +      return target_read_code (memaddr, myaddr, len);
>>> +    });
>>> +
>>> +  return res;
>>>   }
>>>   /* Wrapper of memory_error.  */
>>> diff --git a/gdb/event-top.h b/gdb/event-top.h
>>> index 846d1e48289..d5905527c2a 100644
>>> --- a/gdb/event-top.h
>>> +++ b/gdb/event-top.h
>>> @@ -24,6 +24,8 @@
>>>   #include <signal.h>
>>> +#include "extension.h"
>>> +
>>>   struct cmd_list_element;
>>>   /* The current quit handler (and its type).  This is called from the
>>> @@ -81,6 +83,29 @@ extern void quit_serial_event_set ();
>>>   extern void quit_serial_event_clear ();
>>> +/* Wrap f (args) and handle exceptions by:
>>> +   - returning val, and
>>> +   - calling set_quit_flag or set_force_quit_flag, if needed.  */
>>> +
>>> +template <typename R, R val, typename F, typename... Args>
>>> +static R
>>> +catch_exceptions (F &&f, Args&&... args)
>>> +{
>>> +   try
>>> +     {
>>> +       return f (std::forward<Args> (args)...);
>>> +     }
>>> +   catch (const gdb_exception &ex)
>>> +     {
>>> +       if (ex.reason == RETURN_QUIT)
>>> +     set_quit_flag ();
>>> +       else if (ex.reason == RETURN_FORCED_QUIT)
>>> +     set_force_quit_flag ();
>>> +     }
>>> +
>>> +   return val;
>>> +}
>>> +
>>>   extern void display_gdb_prompt (const char *new_prompt);
>>>   extern void gdb_setup_readline (int);
>>>   extern void gdb_disable_readline (void);
>>> diff --git a/gdb/gdb_bfd.c b/gdb/gdb_bfd.c
>>> index 7e272c719c3..0854d571ecf 100644
>>> --- a/gdb/gdb_bfd.c
>>> +++ b/gdb/gdb_bfd.c
>>> @@ -930,29 +930,6 @@ gdb_bfd_openw (const char *filename, const char 
>>> *target)
>>>     return gdb_bfd_ref_ptr::new_reference (result);
>>>   }
>>> -/* Wrap f (args) and handle exceptions by:
>>> -   - returning val, and
>>> -   - calling set_quit_flag or set_force_quit_flag, if needed.  */
>>> -
>>> -template <typename R, R val, typename F, typename... Args>
>>> -static R
>>> -catch_exceptions (F &&f, Args&&... args)
>>> -{
>>> -   try
>>> -     {
>>> -       return f (std::forward<Args> (args)...);
>>> -     }
>>> -   catch (const gdb_exception &ex)
>>> -     {
>>> -       if (ex.reason == RETURN_QUIT)
>>> -     set_quit_flag ();
>>> -       else if (ex.reason == RETURN_FORCED_QUIT)
>>> -     set_force_quit_flag ();
>>> -     }
>>> -
>>> -   return val;
>>> -}
>>> -
>>>   /* See gdb_bfd.h.  */
>>>   gdb_bfd_ref_ptr
>>>
>>> base-commit: 4e7b18de44be59e8a85b62aa0d89d0c4a54d0dbe
>>> -- 
>>> 2.35.3
>>
> 



More information about the Gdb-patches mailing list