This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: exceptions.KeyboardInterrupt is thrown in gdb.base/random-signal.exp


On 12/01/2015 05:14 PM, Yao Qi wrote:
> Pedro Alves <palves@redhat.com> writes:
> 
>> The test sets a software watchpoint, and resumes the target.  That means
>> the program will be constantly single-stepping, and gdb will be evaluating
>> the watched expression at each single-step.  I'd suspect that the problem
>> is likely that while the program is stopped to evaluate the watched
>> expression, something is calling target_terminal_ours, which restores
>> handle_sigint as SIGINT handler.  Then somehow you're unlucky to manage to
>> ctrl-c at that exact time.  The fix in that case is likely to be to call
>> target_terminal_ours_for_output instead, which doesn't touch the SIGINT
>> handler.
> 
> The cause of this problem is the SIGINT is handled by python.
> 
> As you said, program is being single-stepped constantly, and in each
> stop, python unwinder sniffer is used,
> 
>  #0  pyuw_sniffer (self=<optimised out>, this_frame=<optimised out>, cache_ptr=0xd554f8) at /home/yao/SourceCode/gnu/gdb/git/gdb/python/py-unwind.c:608
>  #1  0x00000000006a10ae in frame_unwind_try_unwinder (this_frame=this_frame@entry=0xd554e0, this_cache=this_cache@entry=0xd554f8, unwinder=0xecd540)
>      at /home/yao/SourceCode/gnu/gdb/git/gdb/frame-unwind.c:107
>  #2  0x00000000006a143f in frame_unwind_find_by_frame (this_frame=this_frame@entry=0xd554e0, this_cache=this_cache@entry=0xd554f8)
>      at /home/yao/SourceCode/gnu/gdb/git/gdb/frame-unwind.c:163
>  #3  0x000000000069dc6b in compute_frame_id (fi=0xd554e0) at /home/yao/SourceCode/gnu/gdb/git/gdb/frame.c:454
>  #4  get_prev_frame_if_no_cycle (this_frame=this_frame@entry=0xd55410) at /home/yao/SourceCode/gnu/gdb/git/gdb/frame.c:1781
>  #5  0x000000000069fdb9 in get_prev_frame_always_1 (this_frame=0xd55410) at /home/yao/SourceCode/gnu/gdb/git/gdb/frame.c:1955
>  #6  get_prev_frame_always (this_frame=this_frame@entry=0xd55410) at /home/yao/SourceCode/gnu/gdb/git/gdb/frame.c:1971
>  #7  0x00000000006a04b1 in get_prev_frame (this_frame=this_frame@entry=0xd55410) at /home/yao/SourceCode/gnu/gdb/git/gdb/frame.c:2213
> 
> and the extension language is set, so GDB changes to cooperative SIGINT
> handling by the extension language.  See extension.c:set_active_ext_lang.
> If ctrl-c is pressed at that time, it is reasonable to me that python
> exception KeyboardInterrupt is thrown out.  In the previous discussion
> https://www.sourceware.org/ml/gdb-patches/2014-01/msg00106.html
> 
> Tom Tromey wrote:
>> The basic idea is that if some extension code is running, then C-c ought
>> to interrupt that code in the way expected by programmers writing code
>> in that language.
> 
> As a GDB developer, I can understand that when python is running, Ctrl-c
> should trigger KeyboardInterrupt, and when the inferior is running,
> Ctrl-c should send interrupt sequence to the remote target.  If we
> accept this fact, we can fix test case, since output of
> KeyboardInterrupt is also correct.  However, as a GDB user, it is quite
> confusing on the expected behavior for ctrl-c, which depends on the time
> ctrl-c is pressed, but I don't have a good idea to fix it, because there
> is no such clear boundary of GDB code and python code from both
> developers' and users' point of view.

IMO, if the inferior is running and target_terminal_inferior is not in
effect (*) then the ctrl-c should _not_ trigger a Python KeyboardInterrupt, but instead
be sent to the target -- if the target is running and we're running some
not-supposed-to-be-interactive Python unwinder code while processing some internal stop
event, we know that the Python code will finish quickly and the target should stop
for the SIGINT very soon.  IOW, we treat the ctrl-c at exactly the wrong time as if
it had been pressed a little sooner or later, outside Python.

(*) - and it shouldn't, while an internal event is being processed.

To handle the case of something going wrong and gdb getting stuck in a loop too
long that the target's SIGINT takes forever to be processed, we could make gdb
react to a _second_ (impatient) ctrl-c as "okay, I'm sick of waiting, please stop
whatever you're doing".  This is like how remote.c handles ctrl-c at exactly the
wrong moment (while an internal event is processed) nowadays:

  https://sourceware.org/ml/gdb-patches/2015-08/msg00574.html

Thanks,
Pedro Alves


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]