aboutsummaryrefslogtreecommitdiff
path: root/gdb/infrun.c
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2014-10-23 17:13:35 +0100
committerPedro Alves <palves@redhat.com>2014-10-29 17:29:26 +0000
commitd3d4baedb6d247c6372678edd15195a1a93c2c6c (patch)
tree7db1f5216dddae6dc675ee5291fc3ab3ea9ecaa1 /gdb/infrun.c
parentd1e8523e40ed5094ed7d5b352ac6b0eabf9f690c (diff)
downloadgdb-d3d4baedb6d247c6372678edd15195a1a93c2c6c.zip
gdb-d3d4baedb6d247c6372678edd15195a1a93c2c6c.tar.gz
gdb-d3d4baedb6d247c6372678edd15195a1a93c2c6c.tar.bz2
PR python/17372 - Python hangs when displaying help()
This is more of a readline/terminal issue than a Python one. PR17372 is a regression in 7.8 caused by the fix for PR17072: commit 0017922d0292d8c374584f6100874580659c9973 Author: Pedro Alves <palves@redhat.com> Date: Mon Jul 14 19:55:32 2014 +0100 Background execution + pagination aborts readline/gdb gdb_readline_wrapper_line removes the handler after a line is processed. Usually, we'll end up re-displaying the prompt, and that reinstalls the handler. But if the output is coming out of handling a stop event, we don't re-display the prompt, and nothing restores the handler. So the next input wakes up the event loop and calls into readline, which aborts. ... gdb/ 2014-07-14 Pedro Alves <palves@redhat.com> PR gdb/17072 * top.c (gdb_readline_wrapper_line): Tweak comment. (gdb_readline_wrapper_cleanup): If readline is enabled, reinstall the input handler callback. The problem is that installing the input handler callback also preps the terminal, putting it in raw mode and with echo disabled, which is bad if we're going to call a command that assumes cooked/canonical mode, and echo enabled, like in the case of the PR, Python's interactive shell. Another example I came up with that doesn't depend on Python is starting a subshell with "(gdb) shell /bin/sh" from a multi-line command. Tests covering both these examples are added. The fix is to revert the original fix for PR gdb/17072, and instead restore the callback handler after processing an asynchronous target event. Furthermore, calling rl_callback_handler_install when we already have some input in readline's line buffer discards that input, which is obviously a bad thing to do while the user is typing. No specific test is added for that, because I first tried calling it even if the callback handler was still installed and that resulted in hundreds of failures in the testsuite. gdb/ 2014-10-29 Pedro Alves <palves@redhat.com> PR python/17372 * event-top.c (change_line_handler): Call gdb_rl_callback_handler_remove instead of rl_callback_handler_remove. (callback_handler_installed): New global. (gdb_rl_callback_handler_remove, gdb_rl_callback_handler_install) (gdb_rl_callback_handler_reinstall): New functions. (display_gdb_prompt): Call gdb_rl_callback_handler_remove and gdb_rl_callback_handler_install instead of rl_callback_handler_remove and rl_callback_handler_install. (gdb_disable_readline): Call gdb_rl_callback_handler_remove instead of rl_callback_handler_remove. * event-top.h (gdb_rl_callback_handler_remove) (gdb_rl_callback_handler_install) (gdb_rl_callback_handler_reinstall): New declarations. * infrun.c (reinstall_readline_callback_handler_cleanup): New cleanup function. (fetch_inferior_event): Install it. * top.c (gdb_readline_wrapper_line) Call gdb_rl_callback_handler_remove instead of rl_callback_handler_remove. (gdb_readline_wrapper_cleanup): Don't call rl_callback_handler_install. gdb/testsuite/ 2014-10-29 Pedro Alves <palves@redhat.com> PR python/17372 * gdb.python/python.exp: Test a multi-line command that spawns interactive Python. * gdb.base/multi-line-starts-subshell.exp: New file.
Diffstat (limited to 'gdb/infrun.c')
-rw-r--r--gdb/infrun.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 7af5e0f..e25f392 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -3107,6 +3107,23 @@ wait_for_inferior (void)
do_cleanups (old_cleanups);
}
+/* Cleanup that reinstalls the readline callback handler, if the
+ target is running in the background. If while handling the target
+ event something triggered a secondary prompt, like e.g., a
+ pagination prompt, we'll have removed the callback handler (see
+ gdb_readline_wrapper_line). Need to do this as we go back to the
+ event loop, ready to process further input. Note this has no
+ effect if the handler hasn't actually been removed, because calling
+ rl_callback_handler_install resets the line buffer, thus losing
+ input. */
+
+static void
+reinstall_readline_callback_handler_cleanup (void *arg)
+{
+ if (async_command_editing_p && !sync_execution)
+ gdb_rl_callback_handler_reinstall ();
+}
+
/* Asynchronous version of wait_for_inferior. It is called by the
event loop whenever a change of state is detected on the file
descriptor corresponding to the target. It can be called more than
@@ -3129,6 +3146,9 @@ fetch_inferior_event (void *client_data)
memset (ecs, 0, sizeof (*ecs));
+ /* End up with readline processing input, if necessary. */
+ make_cleanup (reinstall_readline_callback_handler_cleanup, NULL);
+
/* We're handling a live event, so make sure we're doing live
debugging. If we're looking at traceframes while the target is
running, we're going to need to get back to that mode after