Bug 26266

Summary: SIGINT can cause GDB to skip printing MI stop message.
Product: gdb Reporter: Hafiz Abid Qadeer <abidh>
Component: miAssignee: Not yet assigned to anyone <unassigned>
Status: UNCONFIRMED ---    
Severity: normal CC: pedro
Priority: P2    
Version: HEAD   
Target Milestone: ---   
Host: Target:
Build: Last reconfirmed:

Description Hafiz Abid Qadeer 2020-07-20 14:17:35 UTC
Since 9ccabccd15603dbf9fe988c86708fe644d1398a7, if a ctrl-c is pressed when GDB is running python unwinder, it will make it throw quit exception. But it can happen that python unwinder was running because GDB was printing MI stop message (see the stack trace below). The quit exception will make gdb to skip printing that and MI user will be left in a limbo.

The problem is difficult to reproduce by hand as ctrl-c needs to come at right time. I find that adding some sleep in _execute_unwinders gives a windows to press ctrl-c and it becomes easier to reproduce this problem with the following steps.

1. Build a target executable with a loop.
2. Run gdb in mi mode.
3. Put breakpoint in the loop so that it is hit repeatedly. When gdb hits the breakpoint, it will print the MI stopped message with reason as breakpoint-hit.
4. Give a continue command and the immediately after do ^C. You will notice that GDB will not print a stopped message in this case.

This issue was also briefly discussed on the mailing list.
https://sourceware.org/pipermail/gdb/2020-July/048794.html


The call stack of the exception looks like this:
#3  0x0000555555857ff1 in throw_quit
#4  0x00005555559b9bdb in gdbpy_print_stack_or_quit
#5  0x00005555559aa57f in pyuw_sniffer
#6  0x0000555555838a23 in frame_unwind_try_unwinder
#7  0x0000555555838b90 in frame_unwind_find_by_frame
#8  0x000055555583e7ad in get_frame_type
#9  0x0000555555a445e7 in print_frame_info
   #10 0x0000555555a42a9f in print_stack_frame
#11 0x00005555558b4ebe in print_stop_location
#12 0x00005555558b4f4b in print_stop_event
#13 0x000055555591ab17 in mi_on_normal_stop_1
#14 0x000055555591ad34 in mi_on_normal_stop
#15 0x0000555555618517 in std::_Function_handler<void (bpstats*, int),
void (*)(bpstats*, int)>::_M_invoke(std::_Any_data const&, bpstats*&&,
int&&)
#16 0x00005555558b9d82 in std::function<void (bpstats*,
int)>::operator()(bpstats*, int) const
#17 0x00005555558b93db in gdb::observers::observable<bpstats*, int>::notify
#18 0x00005555558b5832 in normal_stop
Comment 1 Pedro Alves 2023-02-15 21:19:56 UTC
I think this series:

https://inbox.sourceware.org/gdb-patches/20230210233604.2228450-1-pedro@palves.net/T/#m79098ae4ed85a49c9693a47a0ad7a139f63d47dd

finally fixes this problem.

I'm not closing this PR as it'd be nice to have a testcase proving it is really fixed, and stays fixed going forward.

In the linked discussion, Andrew suggested a way to write it:

 "I don't have time to test this right now, but if your diagnosis is
 correct then this should be easy to test.  Write a sniffer that sends
 itself a SIGINT and check you see the problem.

 This should make it possible to create a reliable test case."