aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2014-10-29 11:58:12 +0000
committerPedro Alves <palves@redhat.com>2014-10-29 14:36:21 +0000
commit551cb6a52d99c04055afed182479a8780a15f4a1 (patch)
treefdd8ebac44ef82873b172363c0b69e5902449e13 /gdb
parent84eda397bcf3ebea00383e4a6a864af59723dafd (diff)
downloadgdb-551cb6a52d99c04055afed182479a8780a15f4a1.zip
gdb-551cb6a52d99c04055afed182479a8780a15f4a1.tar.gz
gdb-551cb6a52d99c04055afed182479a8780a15f4a1.tar.bz2
TUI: don't let exceptions escape while handling readline key bindings
I noticed that with: $ TERM=dumb ./gdb -q -nx <c-x,a> Cannot enable the TUI: terminal doesn't support cursor addressing [TERM=dumb] (gdb) The next key the user types is silently eaten. The problem is that we're throwing an exception while in a readline callback that isn't prepared for that: (top-gdb) bt #0 tui_enable () at /home/pedro/gdb/mygit/build/../src/gdb/tui/tui.c:388 #1 0x000000000051f47b in tui_rl_switch_mode (notused1=1, notused2=1) at /home/pedro/gdb/mygit/build/../src/gdb/tui/tui.c:101 #2 0x0000000000768d6f in _rl_dispatch_subseq (key=1, map=0xd069c0 <emacs_ctlx_keymap>, got_subseq=0) at /home/pedro/gdb/mygit/build/../src/readline/readline.c:774 #3 0x0000000000768acb in _rl_dispatch_callback (cxt=0x1ce6190) at /home/pedro/gdb/mygit/build/../src/readline/readline.c:686 #4 0x000000000078120b in rl_callback_read_char () at /home/pedro/gdb/mygit/build/../src/readline/callback.c:170 #5 0x0000000000619445 in rl_callback_read_char_wrapper (client_data=0x0) at /home/pedro/gdb/mygit/build/../src/gdb/event-top.c:166 #6 0x000000000061981b in stdin_event_handler (error=0, client_data=0x0) at /home/pedro/gdb/mygit/build/../src/gdb/event-top.c:372 #7 0x000000000061840e in handle_file_event (data=...) at /home/pedro/gdb/mygit/build/../src/gdb/event-loop.c:762 #8 0x00000000006178f5 in process_event () at /home/pedro/gdb/mygit/build/../src/gdb/event-loop.c:339 #9 0x00000000006179bc in gdb_do_one_event () at /home/pedro/gdb/mygit/build/../src/gdb/event-loop.c:403 #10 0x0000000000617a0c in start_event_loop () at /home/pedro/gdb/mygit/build/../src/gdb/event-loop.c:428 Here, in _rl_dispatch_subseq: 769 770 rl_executing_keymap = map; 771 772 rl_dispatching = 1; 773 RL_SETSTATE(RL_STATE_DISPATCHING); 774 (*map[key].function)(rl_numeric_arg * rl_arg_sign, key); 775 RL_UNSETSTATE(RL_STATE_DISPATCHING); 776 rl_dispatching = 0; 777 778 /* If we have input pending, then the last command was a prefix 779 command. Don't change the state of rl_last_func. Otherwise, GDB is called from line 774, but longjmp'ing at that point leaves rl_dispatching and RL_STATE_DISPATCHING set. Fix this by wrapping tui_rl_switch_mode in a TRY_CATCH. gdb/ 2014-10-29 Pedro Alves <palves@redhat.com> * tui/tui.c (tui_rl_switch_mode): Wrap tui_enable/tui_disable in TRY_CATCH.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog5
-rw-r--r--gdb/tui/tui.c27
2 files changed, 26 insertions, 6 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 6767931..88c18e0 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,8 @@
+2014-10-29 Pedro Alves <palves@redhat.com>
+
+ * tui/tui.c (tui_rl_switch_mode): Wrap tui_enable/tui_disable in
+ TRY_CATCH.
+
2014-10-29 Joel Brobecker <brobecker@adacore.com>
* arm-tdep.c (arm_skip_stack_protector): Return early if
diff --git a/gdb/tui/tui.c b/gdb/tui/tui.c
index ca66ccd..cb85fb0 100644
--- a/gdb/tui/tui.c
+++ b/gdb/tui/tui.c
@@ -90,15 +90,30 @@ static Keymap tui_readline_standard_keymap;
static int
tui_rl_switch_mode (int notused1, int notused2)
{
- if (tui_active)
+ volatile struct gdb_exception ex;
+
+ /* Don't let exceptions escape. We're in the middle of a readline
+ callback that isn't prepared for that. */
+ TRY_CATCH (ex, RETURN_MASK_ALL)
{
- tui_disable ();
- rl_prep_terminal (0);
+ if (tui_active)
+ {
+ tui_disable ();
+ rl_prep_terminal (0);
+ }
+ else
+ {
+ /* If tui_enable throws, we'll re-prep below. */
+ rl_deprep_terminal ();
+ tui_enable ();
+ }
}
- else
+ if (ex.reason < 0)
{
- rl_deprep_terminal ();
- tui_enable ();
+ exception_print (gdb_stderr, ex);
+
+ if (!tui_active)
+ rl_prep_terminal (0);
}
/* Clear the readline in case switching occurred in middle of