Skip to content
This repository has been archived by the owner on Aug 17, 2022. It is now read-only.

Commit

Permalink
Change SIGINT handler for extension languages only when target termin…
Browse files Browse the repository at this point in the history
…al is ours

I see a timeout in gdb.base/random-signal.exp,

 Continuing.^M
 PASS: gdb.base/random-signal.exp: continue
 ^CPython Exception <type 'exceptions.KeyboardInterrupt'> <type
 exceptions.KeyboardInterrupt'>: ^M
 FAIL: gdb.base/random-signal.exp: stop with control-c (timeout)

it can be reproduced by running random-signal.exp with native-gdbserver
in a loop, like this, and the fail will be shown in about 20 runs,

$ (set -e; while true; do make check RUNTESTFLAGS="--target_board=native-gdbserver random-signal.exp"; done)

In the test, the program is being single-stepped for software watchpoint,
and in each internal 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

when GDB goes to python extension, or other language extension, the
SIGINT handler is changed, and is restored when GDB leaves extension
language.  GDB only stays in extension language for a very short period
in this case, but if ctrl-c is pressed at that moment, python extension
will handle the SIGINT, and exceptions.KeyboardInterrupt is shown.

Language extension is used in GDB side rather than inferior side,
so GDB should only change SIGINT handler for extension language when
the terminal is ours (not inferior's).  This is what this patch does.
With this patch applied, I run random-signal.exp in a loop for 18
hours, and no fail is shown.

gdb:

2016-01-08  Yao Qi  <[email protected]>

	* extension.c: Include target.h.
	(set_active_ext_lang): Only call install_gdb_sigint_handler,
	check_quit_flag, and set_quit_flag if target_terminal_is_ours
	returns false.
	(restore_active_ext_lang): Likewise.
	* target.c (target_terminal_is_ours): New function.
	* target.h (target_terminal_is_ours): Declare.
  • Loading branch information
Yao Qi committed Jan 8, 2016
1 parent 5a0dd67 commit 2f99e8f
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 21 deletions.
10 changes: 10 additions & 0 deletions gdb/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
2016-01-08 Yao Qi <[email protected]>

* extension.c: Include target.h.
(set_active_ext_lang): Only call install_gdb_sigint_handler,
check_quit_flag, and set_quit_flag if target_terminal_is_ours
returns false.
(restore_active_ext_lang): Likewise.
* target.c (target_terminal_is_ours): New function.
* target.h (target_terminal_is_ours): Declare.

2016-01-07 Maciej W. Rozycki <[email protected]>

* mips-tdep.c (mips_breakpoint_from_pc): Rename local `status'
Expand Down
51 changes: 30 additions & 21 deletions gdb/extension.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include "defs.h"
#include <signal.h>
#include "target.h"
#include "auto-load.h"
#include "breakpoint.h"
#include "event-top.h"
Expand Down Expand Up @@ -746,19 +747,24 @@ set_active_ext_lang (const struct extension_language_defn *now_active)
= XCNEW (struct active_ext_lang_state);

previous->ext_lang = active_ext_lang;
previous->sigint_handler.handler_saved = 0;
active_ext_lang = now_active;

/* If the newly active extension language uses cooperative SIGINT handling
then ensure GDB's SIGINT handler is installed. */
if (now_active->language == EXT_LANG_GDB
|| now_active->ops->check_quit_flag != NULL)
install_gdb_sigint_handler (&previous->sigint_handler);

/* If there's a SIGINT recorded in the cooperative extension languages,
move it to the new language, or save it in GDB's global flag if the newly
active extension language doesn't use cooperative SIGINT handling. */
if (check_quit_flag ())
set_quit_flag ();
if (target_terminal_is_ours ())
{
/* If the newly active extension language uses cooperative SIGINT
handling then ensure GDB's SIGINT handler is installed. */
if (now_active->language == EXT_LANG_GDB
|| now_active->ops->check_quit_flag != NULL)
install_gdb_sigint_handler (&previous->sigint_handler);

/* If there's a SIGINT recorded in the cooperative extension languages,
move it to the new language, or save it in GDB's global flag if the
newly active extension language doesn't use cooperative SIGINT
handling. */
if (check_quit_flag ())
set_quit_flag ();
}

return previous;
}
Expand All @@ -772,16 +778,19 @@ restore_active_ext_lang (struct active_ext_lang_state *previous)

active_ext_lang = previous->ext_lang;

/* Restore the previous SIGINT handler if one was saved. */
if (previous->sigint_handler.handler_saved)
install_sigint_handler (&previous->sigint_handler);

/* If there's a SIGINT recorded in the cooperative extension languages,
move it to the new language, or save it in GDB's global flag if the newly
active extension language doesn't use cooperative SIGINT handling. */
if (check_quit_flag ())
set_quit_flag ();

if (target_terminal_is_ours ())
{
/* Restore the previous SIGINT handler if one was saved. */
if (previous->sigint_handler.handler_saved)
install_sigint_handler (&previous->sigint_handler);

/* If there's a SIGINT recorded in the cooperative extension languages,
move it to the new language, or save it in GDB's global flag if the
newly active extension language doesn't use cooperative SIGINT
handling. */
if (check_quit_flag ())
set_quit_flag ();
}
xfree (previous);
}

Expand Down
8 changes: 8 additions & 0 deletions gdb/target.c
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,14 @@ target_terminal_is_inferior (void)

/* See target.h. */

int
target_terminal_is_ours (void)
{
return (terminal_state == terminal_is_ours);
}

/* See target.h. */

void
target_terminal_inferior (void)
{
Expand Down
4 changes: 4 additions & 0 deletions gdb/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -1503,6 +1503,10 @@ extern int target_remove_breakpoint (struct gdbarch *gdbarch,

extern int target_terminal_is_inferior (void);

/* Returns true if our terminal settings are in effect. */

extern int target_terminal_is_ours (void);

/* Initialize the terminal settings we record for the inferior,
before we actually run the inferior. */

Expand Down

0 comments on commit 2f99e8f

Please sign in to comment.