public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
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

  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).