old-cross-binutils/gdb/testsuite/gdb.base/multi-line-starts-subshell.exp
Pedro Alves d3d4baedb6 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 0017922d02
 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.
2014-10-29 17:29:26 +00:00

55 lines
1.7 KiB
Text

# Copyright (C) 2014 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Test spawning a subshell from a multi-line command, where the last
# prompt displayed is a secondary prompt. GDB used to have a bug
# where in this case the subshell would start with the wrong terminal
# settings. See PR python/17372.
gdb_exit
gdb_start
# The subshell's prompt.
set shell_prompt "gdb-subshell$ "
set shell_prompt_re [string_to_regexp $shell_prompt]
# Point HOME nowhere to avoid the shell sourcing the user's init
# scripts.
set shell_cmd "HOME=/dev/null PS1=\"$shell_prompt\" /bin/sh"
set test "spawn subshell from multi-line"
gdb_test_multiple "if 1\nshell ${shell_cmd}\nend" $test {
-re "$shell_prompt_re$" {
pass $test
# Now check that shell input works and that echo is enabled.
set test "shell input works"
send_gdb "echo foo\n"
gdb_expect {
-re "^echo foo\r\nfoo\r\n$shell_prompt_re$" {
pass $test
}
timeout {
fail "$test (timeout)"
}
}
# Exit the subshell, back to GDB
gdb_test "exit" ".*" "exit shell"
}
}
# Check that we restore input in GDB correctly.
gdb_test "print 1" "^print 1\r\n.. = 1" "gdb input still works"