diff options
-rw-r--r-- | gdb/event-top.c | 20 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/eof-exit.exp | 88 | ||||
-rw-r--r-- | gdb/testsuite/lib/gdb.exp | 9 |
3 files changed, 116 insertions, 1 deletions
diff --git a/gdb/event-top.c b/gdb/event-top.c index 8890c4f..c1a95a4 100644 --- a/gdb/event-top.c +++ b/gdb/event-top.c @@ -766,7 +766,25 @@ command_line_handler (gdb::unique_xmalloc_ptr<char> &&rl) /* stdin closed. The connection with the terminal is gone. This happens at the end of a testsuite run, after Expect has hung up but GDB is still alive. In such a case, we just quit - gdb killing the inferior program too. */ + gdb killing the inferior program too. This also happens if the + user sends EOF, which is usually bound to ctrl+d. + + What we want to do in this case is print "quit" after the GDB + prompt, as if the user had just typed "quit" and pressed return. + + This used to work just fine, but unfortunately, doesn't play well + with readline's bracketed paste mode. By the time we get here, + readline has already sent the control sequence to leave bracketed + paste mode, and this sequence ends with a '\r' character. As a + result, if bracketed paste mode is on, and we print quit here, + then this will overwrite the prompt. + + To work around this issue, when bracketed paste mode is enabled, + we first print '\n' to move to the next line, and then print the + quit. This isn't ideal, but avoids corrupting the prompt. */ + const char *value = rl_variable_value ("enable-bracketed-paste"); + if (value != nullptr && strcmp (value, "on") == 0) + printf_unfiltered ("\n"); printf_unfiltered ("quit\n"); execute_command ("quit", 1); } diff --git a/gdb/testsuite/gdb.base/eof-exit.exp b/gdb/testsuite/gdb.base/eof-exit.exp new file mode 100644 index 0000000..d604d02 --- /dev/null +++ b/gdb/testsuite/gdb.base/eof-exit.exp @@ -0,0 +1,88 @@ +# Copyright (C) 2022 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/>. + +# This test script checks how GDB handles exiting with ctrl-d. + +# Start GDB, and then close it by sendig ctrl-d. Check that the +# string 'quit' appears where we expect it too. +proc run_test {} { + clean_restart + + # The gdb_start call above swallows the GDB prompt, and we want + # the prompt for the test below. + # + # Send a newline character, which will cause GDB to redisplay the + # prompt. + send_gdb "\n" + gdb_test_multiple "" "discard newline" { + -re "^\r\n" { + } + } + + # Send GDB a ctrl-d. Check that we see the 'quit' string in the + # expected place. + send_gdb "\004" + gdb_test_multiple "" "close GDB with eof" { + -re "$::gdb_prompt \[^\n\]*\r\[^\n\]*quit" { + fail "$gdb_test_name (misplaced \\r)" + } + -re "$::gdb_prompt \[^\n\]*\r\[^\n\]*\r\nquit\r\n" { + # For versions of readline that don't include the + # RL_STATE_EOF patch, then the 'quit' is printed on the + # subsequent line. + kfail gdb/28833 "$gdb_test_name (older version of readline)" + } + -re "$::gdb_prompt quit\[^\n\]*\r\n\[^\n\]*\r\n$" { + # There was a bug where GDB would print an extra blank + # line after the 'quit', this catches that case. + fail $gdb_test_name + } + -re "$::gdb_prompt quit\[^\n\]*\r\n\[^\n\]*$" { + pass $gdb_test_name + } + eof { + fail "$gdb_test_name (missed the prompt)" + } + } +} + +with_test_prefix "default" { + run_test +} + +save_vars { env(TERM) } { + setenv TERM ansi + + with_test_prefix "with non-dump terminal" { + run_test + + save_vars { env(INPUTRC) } { + + # Create an inputrc file that turns bracketed paste mode + # on. This is usually turned off (see lib/gdb.exp), but + # for the next test we want to see what happens with this + # on. + set inputrc [standard_output_file inputrc] + set fd [open "$inputrc" w] + puts $fd "set enable-bracketed-paste on" + close $fd + + setenv INPUTRC "$inputrc" + with_test_prefix "with bracketed-paste-mode on" { + run_test + } + } + } +} diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index a35d08a..08726f7 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -2151,6 +2151,15 @@ proc default_gdb_start { } { -re "\[\r\n\]$gdb_prompt $" { verbose "GDB initialized." } + -re "\[\r\n\]\033\\\[.2004h$gdb_prompt $" { + # This special case detects what happens when GDB is + # started with bracketed paste mode enabled. This mode is + # usually forced off (see setting of INPUTRC in + # default_gdb_init), but for at least one test we turn + # bracketed paste mode back on, and then start GDB. In + # that case, this case is hit. + verbose "GDB initialized." + } -re "$gdb_prompt $" { perror "GDB never initialized." unset gdb_spawn_id |