bug-readline
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: pending signal after rl_callback_read_char


From: Simon Marchi
Subject: Re: pending signal after rl_callback_read_char
Date: Tue, 20 Sep 2022 15:13:05 -0400
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.2.2

> It could be a timing issue: the signal arrives after rl_callback_read_char
> checks for it and before it returns, but there's not a lot it can do about
> that. That's why we have rl_check_signals() now.

That's what I think, there's a window in rl_callback_read_char after the
last time rl_check_signals was called, but before the original (user's)
signal handlers are put back in place.  If the SIGINT arrives during
that window, it will go unnoticed until the next call to
rl_callback_read_char (or some other readline function).

See my comment here: 
https://inbox.sourceware.org/gdb-patches/9c5a599c-faf3-940b-745b-3528cd72fcdb@simark.ca/

I have a way to reproduce it fairly easily in GDB with a minor
modification, you can probably adapt it to use a dummy program using
readline.

1. Reset the binutils-gdb repo to 49c3ed081fed ("PowerPC64 pcrel got
relocs against local symbols"), the commit before Tom's fix.

2. Apply the following patch to GDB and build:

diff --git a/readline/readline/callback.c b/readline/readline/callback.c
index 93f23d97bc20..0f5d3e26de94 100644
--- a/readline/readline/callback.c
+++ b/readline/readline/callback.c
@@ -264,6 +264,13 @@ rl_callback_read_char (void)
        eof = readline_internal_char ();
 
       RL_CHECK_SIGNALS ();
+
+      /* wait 2 s */
+      printf("gonna wait\n");
+      for (int i = 0; i < 2000; ++i)
+       usleep (1000);
+      printf("done wait\n");
+
       if (rl_done == 0 && _rl_want_redisplay)
        {
          (*rl_redisplay_function) ();

This gives us a 2s window to send a SIGINT.

3. Start GDB:

  $ ./gdb -nx --data-directory=data-directory -q

4. Type one (any) character.  This should print "gonna wait".  Then,
   within the next two seconds, type ^C to send a SIGINT.

5. "done wait" should then appear, showing the wait shown above is done.
   You won't see any reaction from GDB about the ^C.  If you attach to
   GDB with GDB, you can see it is stored in _rl_pending_signal:

(top-gdb) p _rl_caught_signal 
$1 = 2

6. Type another character, GDB will show "Quit", showing that the SIGINT
   has finally been processed.

I think that it could be fixed in readline by doing the following when
reinstalling the old signal handlers:

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

Simon



reply via email to

[Prev in Thread] Current Thread [Next in Thread]