public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Simon Marchi <simark@simark.ca>
To: Tom de Vries <tdevries@suse.de>, gdb-patches@sourceware.org
Subject: Re: [RFC][gdb] Handle pending ^C after rl_callback_read_char
Date: Tue, 13 Sep 2022 10:15:54 -0400	[thread overview]
Message-ID: <9c5a599c-faf3-940b-745b-3528cd72fcdb@simark.ca> (raw)
In-Reply-To: <20220913125619.GA15500@delia.home>



On 2022-09-13 08:56, Tom de Vries via Gdb-patches wrote:
> Hi,
> 
> In completion tests in various test-cases, we've been running into these
> "clearing input line" timeouts:
> ...
> (gdb) $cmd^GPASS: gdb.gdb/unittest.exp: tab complete "$cmd"
> FAIL: gdb.gdb/unittest.exp: tab complete "$cmd" (clearing input line) (timeout)
> ...
> where $cmd == "maintenance selftest name_that_does_not_exist".
> 
> AFAIU, the following scenario happens:
> - expect sends "$cmd\t"
> - gdb detects the stdin event, and calls rl_callback_read_char until it
>   comes to handle \t
> - readline interprets the \t as completion, tries to complete, fails to do so
>   outputs a bell (^G)
> - expect sees the bell, and proceeds to send ^C
> - readline is still in the call to rl_callback_read_char, and stores the
>   signal in _rl_caught_signal
> - readline returns from the call to rl_callback_read_char, without having
>   handled _rl_caught_signal
> - gdb goes to wait for the next event
> - expect times out waiting for "Quit", the expected reaction for ^C
> 
> Fix this by handling pending signals after each call to rl_callback_read_char.
> 
> The fix is only available for readline 8.x, if --with-system-readline provides
> an older version, then the fix is disabled due to missing function
> rl_check_signals.

Thanks a lot for looking into this.

So, readline installs its own sigint handler, which just saves the
signal number somewhere.  It then checks on it synchronously at
different points using RL_CHECK_SIGNALS.

I put a breakpoint on rl_clear_signals, which is where it restores the
old signal handlers, and I think that the window that is between the last call to
RL_CHECK_SIGNALS and rl_clear_signals (so, the window where the signal
number is just saved but the signal is not handled) is this:

  https://gitlab.com/gnutools/binutils-gdb/-/blob/e9a241e87b42f902d0408704df6bbcd8bf465a46/readline/readline/callback.c#L266-304

Putting a 50ms delay somewhere in this window, I can reproduce the
problem all the time, with your modified gdb.gdb/unittest.exp.

diff --git a/readline/readline/callback.c b/readline/readline/callback.c
index 93f23d97bc20..e5a0560fd5f9 100644
--- a/readline/readline/callback.c
+++ b/readline/readline/callback.c
@@ -264,6 +264,11 @@ rl_callback_read_char (void)
        eof = readline_internal_char ();
 
       RL_CHECK_SIGNALS ();
+
+      /* wait 50 ms */
+      for (int i = 0; i < 50; ++i)
+       usleep (1000);
+
       if (rl_done == 0 && _rl_want_redisplay)
        {
          (*rl_redisplay_function) ();

And then with your fix below apply, the test passes fine.  So, the fix
LGTM.  My only question would be, is this a readline bug?  Should
readline do:

 - block signals
 - call RL_CHECK_SIGNALS
 - restore old handlers
 - unblock signals

to avoid that window of lost signals?  Or is this (your fix) the way
readline is supposed to be used?  In any case, I'm fine with your fix
going in even if it's a temporary measure.

Simon

  reply	other threads:[~2022-09-13 14:15 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-13 12:56 Tom de Vries
2022-09-13 14:15 ` Simon Marchi [this message]
2022-09-13 14:32   ` Tom de Vries
2022-09-16 14:28     ` Tom de Vries
2022-09-16 14:50       ` Simon Marchi

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=9c5a599c-faf3-940b-745b-3528cd72fcdb@simark.ca \
    --to=simark@simark.ca \
    --cc=gdb-patches@sourceware.org \
    --cc=tdevries@suse.de \
    /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).