diff options
author | Pedro Alves <palves@redhat.com> | 2014-10-29 11:58:12 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2014-10-29 14:36:21 +0000 |
commit | 551cb6a52d99c04055afed182479a8780a15f4a1 (patch) | |
tree | fdd8ebac44ef82873b172363c0b69e5902449e13 /gdb/tui/tui.c | |
parent | 84eda397bcf3ebea00383e4a6a864af59723dafd (diff) | |
download | binutils-551cb6a52d99c04055afed182479a8780a15f4a1.zip binutils-551cb6a52d99c04055afed182479a8780a15f4a1.tar.gz binutils-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/tui/tui.c')
-rw-r--r-- | gdb/tui/tui.c | 27 |
1 files changed, 21 insertions, 6 deletions
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 |