From: Simon Marchi <simark@simark.ca>
To: Andrew Burgess <aburgess@redhat.com>, gdb-patches@sourceware.org
Subject: Re: [PATCHv2 1/3] gdb: work around prompt corruption caused by bracketed-paste-mode
Date: Fri, 25 Mar 2022 14:32:42 -0400 [thread overview]
Message-ID: <97d5c0ac-9771-f55e-0689-c00604861f5e@simark.ca> (raw)
In-Reply-To: <0b46b6578a435b06af1896a8c59403a0df8dc758.1647253263.git.aburgess@redhat.com>
On 2022-03-14 06:23, Andrew Burgess via Gdb-patches wrote:
> In this commit:
>
> commit b4f26d541aa7224b70d363932e816e6e1a857633
> Date: Tue Mar 2 13:42:37 2021 -0700
>
> Import GNU Readline 8.1
>
> We imported readline 8.1 into GDB. As a consequence bug PR cli/28833
> was reported. This bug spotted that, when the user terminated GDB by
> sending EOF (usually bound to Ctrl+d), the last prompt would become
> corrupted. Here's what happens, the user is sat at a prompt like
> this:
>
> (gdb)
>
> And then the user sends EOF (Ctrl+d), we now see this:
>
> quit)
> ... gdb terminates, and we return to the shell ...
>
> Notice the 'quit' was printed over the prompt.
>
> This problem is a result of readline 8.1 enabling bracketed paste mode
> by default. This problem is present in readline 8.0 too, but in that
> version of readline bracketed paste mode is off by default, so a user
> will not see the bug unless they specifically enable the feature.
>
> Bracketed paste mode is available in readline 7.0 too, but the bug
> is not present in this version of readline, see below for why.
>
> What causes this problem is how readline disables bracketed paste
> mode. Bracketed paste mode is a terminal feature that is enabled and
> disabled by readline emitting a specific escape sequence. The problem
> for GDB is that the escape sequence to disable bracketed paste mode
> includes a '\r' character at the end, see this thread for more
> details:
>
> https://lists.gnu.org/archive/html/bug-bash/2018-01/msg00097.html
>
> The change to add the '\r' character to the escape sequence used to
> disable bracketed paste mode was introduced between readline 7.0 and
> readline 8.0, this is why the bug would not occur when using older
> versions of readline (note: I don't know if its even possible to build
> GDB using readline 7.0. That really isn't important, I'm just
> documenting the history of this issue).
>
> So, the escape sequence to disable bracketed paste mode is emitted
> from the readline function rl_deprep_terminal, this is called after
> the user has entered a complete command and pressed return, or, if the
> user sends EOF.
>
> However, these two cases are slightly different. In the first case,
> when the user has entered a command and pressed return, the cursor
> will have moved to the next, empty, line, before readline emits the
> escape sequence to leave bracketed paste mode. The final '\r'
> character moves the cursor back to the beginning of this empty line,
> which is harmless.
>
> For the EOF case though, this is not what happens. Instead, the
> escape sequence to leave bracketed paste mode is emitted on the same
> line as the prompt. The final '\r' moves the cursor back to the start
> of the prompt line. This leaves us ready to override the prompt.
>
> It is worth noting, that this is not the intended behaviour of
> readline, in rl_deprep_terminal, readline should emit a '\n' character
> when EOF is seen. However, due to a bug in readline this does not
> happen (the _rl_eof_found flag is never set). This is the first
> readline bug that effects GDB.
>
> GDB prints the 'quit' message from command_line_handler (in
> event-top.c), this function is called (indirectly) from readline to
> process the complete command line, but also in the EOF case (in which
> case the command line is set to nullptr). As this is part of the
> callback to process a complete command, this is called after readline
> has disabled bracketed paste mode (by calling rl_deprep_terminal).
>
> And so, when bracketed paste mode is in use, rl_deprep_terminal leaves
> the cursor at the start of the prompt line (in the EOF case), and
> command_line_handler then prints 'quit', which overwrites the prompt.
>
> The solution to this problem is to print the 'quit' message earlier,
> before rl_deprep_terminal is called. This is easy to do by using the
> rl_deprep_term_function hook. It is this hook that usually calls
> rl_deprep_terminal, however, if we replace this with a new function,
> we can print the 'quit' string, and then call rl_deprep_terminal
> ourselves. This allows the 'quit' to be printed before
> rl_deprep_terminal is called.
>
> The problem here is that there is no way in rl_deprep_terminal to know
> if readline is processing EOF or not, and as a result, we don't know
> when we should print 'quit'. This is the second readline bug that
> effects GDB.
>
> Both of these readline issues are discussed in this thread:
>
> https://lists.gnu.org/archive/html/bug-readline/2022-02/msg00021.html
>
> The result of that thread was that readline was patched to address
> both of these issues.
>
> Now it should be easy to backport the readline fix to GDB's in tree
> copy of readline, and then change GDB to make use of these fixes to
> correctly print the 'quit' string.
>
> However, we are just about to branch GDB 12, and there is concern from
> some that changing readline this close to a new release is a risky
> idea, see this thread:
>
> https://sourceware.org/pipermail/gdb-patches/2022-March/186391.html
>
> So, this commit doesn't change readline at all. Instead, this commit
> is the smallest possible GDB change in order to avoid the prompt
> corruption.
>
> In this commit I change GDB to print the 'quit' string on the line
> after the prompt, but only when bracketed paste mode is on. This
> avoids the overwriting issue, the user sees this:
>
> (gdb)
> quit
> ... gdb terminates, and returns to the shell ...
>
> This isn't ideal, but is better than the existing behaviour. After
> GDB 12 has branched, we can backport the readline fix, and apply a
> real fix to GDB.
>
> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28833
Hi Andrew,
I see this test fail on the following setup:
- Ubuntu 18.04
- Building with --with-system-readline (distro package libreadline-dev
installed, which is readline 7.0)
^[[?2004h(gdb) set height 0^M
^[[?2004l^[[?2004h(gdb) set width 0^M
^[[?2004l^[[?2004h(gdb) dir^M
^[[?2004l^[[?2004hReinitialize source path to empty? (y or n) y^M
^[[?2004lSource directories searched: $cdir:$cwd^M
^[[?2004h(gdb) dir /build/gdb/testsuite/../../../binutils-gdb/gdb/testsuite/gdb.base^M
^[[?2004lSource directories searched: /build/gdb/testsuite/../../../binutils-gdb/gdb/testsuite/gdb.base:$cdir:$cwd^M
^[[?2004h(gdb) ^M
^[[?2004l^[[?2004h(gdb) ^[[?2004l^M
quit^M
FAIL: gdb.base/eof-exit.exp: with non-dump terminal: with bracketed-paste-mode on: close GDB with eof (missed the prompt)
It's clearly related to bracketed-paste-mode, since these 2004 escape
sequences turn bracketed-paste-mode on and off (accordin to
https://wiki2.org/en/ISO/IEC_6429). But I don't know what happens
exactly.
Here's a Dockerfile that can be used to reproduce the failure, hopefully
it makes it easier:
FROM ubuntu:18.04
RUN apt-get -y update && \
apt-get -y full-upgrade && \
DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install build-essential flex bison git texinfo libreadline-dev dejagnu libexpat1-dev libgmp-dev
RUN git clone --depth 1 git://sourceware.org/git/binutils-gdb.git
RUN mkdir build
WORKDIR /build
RUN ../binutils-gdb/configure --with-system-readline
RUN make -j $(nproc) all-gdb
WORKDIR /build/gdb
RUN make check TESTS="gdb.base/eof-exit.exp"
Simon
next prev parent reply other threads:[~2022-03-25 18:32 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-07 15:13 [PATCH 0/2] Fix GDB prompt corruption issue Andrew Burgess
2022-03-07 15:13 ` [PATCH 1/2] readline: back-port changes needed to properly detect EOF Andrew Burgess
2022-03-09 17:45 ` Tom Tromey
2022-03-07 15:13 ` [PATCH 2/2] gdb: handle bracketed-paste-mode and ctrl-d correctly Andrew Burgess
2022-03-07 17:10 ` Eli Zaretskii
2022-03-08 9:45 ` Andrew Burgess
2022-03-08 12:10 ` Eli Zaretskii
2022-03-14 10:23 ` [PATCHv2 0/3] Fix GDB prompt corruption issue Andrew Burgess
2022-03-14 10:23 ` [PATCHv2 1/3] gdb: work around prompt corruption caused by bracketed-paste-mode Andrew Burgess
2022-03-16 17:31 ` Tom Tromey
2022-03-16 20:45 ` Andrew Burgess
2022-03-17 8:22 ` Aktemur, Tankut Baris
2022-03-25 18:32 ` Simon Marchi [this message]
2022-03-26 14:02 ` Andrew Burgess
2022-03-27 0:59 ` Simon Marchi
2022-03-14 10:23 ` [PATCHv2 2/3] readline: back-port changes needed to properly detect EOF Andrew Burgess
2022-03-14 10:23 ` [PATCHv2 3/3] gdb: handle bracketed-paste-mode and EOF correctly Andrew Burgess
2022-03-21 15:58 ` [PATCHv3 0/2] Fix GDB prompt corruption issue Andrew Burgess
2022-03-21 15:58 ` [PATCHv3 1/2] readline: back-port changes needed to properly detect EOF Andrew Burgess
2022-03-21 15:58 ` [PATCHv3 2/2] gdb: handle bracketed-paste-mode and EOF correctly Andrew Burgess
2022-03-29 14:26 ` [PATCHv4 0/3] Fix GDB prompt corruption issue Andrew Burgess
2022-03-29 14:26 ` [PATCHv4 1/3] gdb: improved EOF handling when using readline 7 Andrew Burgess
2022-03-29 14:26 ` [PATCHv4 2/3] readline: back-port changes needed to properly detect EOF Andrew Burgess
2022-03-29 14:26 ` [PATCHv4 3/3] gdb: handle bracketed-paste-mode and EOF correctly Andrew Burgess
2022-04-21 16:49 ` [PATCHv4 0/3] Fix GDB prompt corruption issue Andrew Burgess
2022-04-22 17:52 ` Andrew Burgess
2022-04-26 14:27 ` Andrew Burgess
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=97d5c0ac-9771-f55e-0689-c00604861f5e@simark.ca \
--to=simark@simark.ca \
--cc=aburgess@redhat.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).