[gdb/cli] Clear line buffer on ^C

Gdb has the ability to gather input over several lines [1], for instance this:
...
(gdb) print 1
$1 = 1
(gdb)
...
can also be typed as:
...
(gdb) print\
 1
$2 = 1
(gdb)
...

Furthermore, if we type a command but change our mind, we can abort using ^C
and start over using a fresh gdb prompt [2]:
...
(gdb) print 1️ Quit
(gdb) echo 1\n
1
(gdb)
...

Now say we type a multi-line command but abort it, we get:
...
(gdb) print\
 1️ Quit
(gdb) echo 1\n
️ Undefined command: "printecho".  Try "help".
(gdb)
...

Using "set trace-commands on", we can see what happened:
...
+printecho 1\n
..

Gdb has prepended the first line of the cancelled multi-line command to the
following command.

Fix this by clearing current_ui->line_buffer on catching a gdb_exception in
start_event_loop.

Tested on x86_64-linux.

Approved-By: Andrew Burgess <aburgess@redhat.com>

PR cli/33063
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=33063

[1] https://sourceware.org/gdb/current/onlinedocs/gdb.html/Output.html
[2] https://sourceware.org/gdb/current/onlinedocs/gdb.html/Quitting-GDB.html
This commit is contained in:
Tom de Vries
2025-07-22 22:26:05 +02:00
parent 5b763a4708
commit cf5a7801bd
2 changed files with 31 additions and 0 deletions

View File

@@ -420,6 +420,7 @@ start_event_loop ()
get around to resetting the prompt, which leaves readline
in a messed-up state. Reset it here. */
current_ui->prompt_state = PROMPT_NEEDED;
current_ui->line_buffer.clear ();
top_level_interpreter ()->on_command_error ();
/* This call looks bizarre, but it is required. If the user
entered a command that caused an error,

View File

@@ -21,6 +21,9 @@
gdb_exit
gdb_start
set bs "\\"
set re_bs [string_to_regexp $bs]
set test "print 1\\\\n + 2"
gdb_test_multiple "print 1\\\n + 2" $test {
-re "^print 1\\\\\r\n \\+ 2\r\n\\\$$decimal = 3\r\n$gdb_prompt $" {
@@ -34,3 +37,30 @@ gdb_test_multiple "print 1\\\n2" $test {
pass $test
}
}
with_test_prefix "cancel multiline" {
send_gdb "print$bs\n 1"
gdb_test_multiple "" "setup" {
-re "print$re_bs\r\n 1" {
pass $gdb_test_name
}
}
send_gdb "\003"
gdb_test_multiple "" "cancel" {
-re -wrap "" {
pass $gdb_test_name
}
}
# Regression test for PR cli/33063.
gdb_test_multiple "print 2" "command after cancel" {
-re -wrap " = 2" {
pass $gdb_test_name
}
-re -wrap "" {
# Avoid undefined command error.
fail $gdb_test_name
}
}
}