Please keep me CC'd as I'm not subscribed to the list. Something "fun" today. First off: yes, I should have been using 'bsdgrep -r -- "-2011" .', and yes that works fine, but that's besides the point. Here we go: % bsdgrep -r "-2011" . ^Z Suspended % bg [1] bsdgrep -r -2011 . & % qqqqqqqqqqq % % fg(standard input):qqqqqqqqqfgfg bsdgrep -r -2011 . ^C % Let me explain what transpired from an input perspective: 1. Ran bsdgrep -r "-2011" . 2. Pressed Ctrl-Z 3. Typed bg 4. Typed "q" 20 times in a row exactly 5. Pressed Ctrl-C 6. Typed "fg" and pressed Enter 7. Typed "ffgg" and pressed Enter 8. Pressed Ctrl-Z and Enter 9. Pressed Ctrl-C What's going on here? Where is the famous "Suspended (tty input)"? It gets more interesting. Here's another one: % bsdgrep -r "-2011" . ^Z Suspended % bg [1] bsdgrep -r -2011 . & % g(standard input):f fg gfg: Command not found. [1] + Suspended (tty input) bsdgrep -r -2011 . % jobs [1] + Suspended (tty input) bsdgrep -r -2011 . % fg bsdgrep -r -2011 . % And what transpired input-wise: 1. Ran bsdgrep -r "-2011" . 2. Pressed Ctrl-Z 3. Typed bg 4. Typed "fg" and Enter 5. Typed "fg" again and pressed Enter 6. Typed "jobs" and pressed Enter 7. Typed "fg" and pressed Enter 8. Pressed Ctrl-D Some facts: - Fully 100% reproducible - Tested only on RELENG_9 (source from 2012/10/21) - Happens regardless of shell (bash and csh tested; csh w/out dot files) - Similar behaviour happens with our base system grep (GNU grep) but sometimes it manifests itself in a weirder way - bsdgrep and GNU grep are both in state "ttyin" when this happens CC'ing some folks who might have some ideas or can explain how to troubleshoot this one. For the signal part, I believe this would be SIGTTIN. -- | Jeremy Chadwick jdc at koitsu.org | | UNIX Systems Administrator http://jdc.koitsu.org/ | | Mountain View, CA, US | | Making life hard for others since 1977. PGP 4BD6C0CB |
Konstantin Belousov
2012-Oct-23 20:39 UTC
pty/tty or signal strangeness, or grep/bsdgrep bug?
On Tue, Oct 23, 2012 at 07:27:03AM -0700, Jeremy Chadwick wrote:> Please keep me CC'd as I'm not subscribed to the list. > > Something "fun" today. First off: yes, I should have been using > 'bsdgrep -r -- "-2011" .', and yes that works fine, but that's besides > the point. Here we go: > > % bsdgrep -r "-2011" . > ^Z > Suspended > % bg > [1] bsdgrep -r -2011 . & > % qqqqqqqqqqq > % > % fg(standard input):qqqqqqqqqfgfg > > bsdgrep -r -2011 . > ^C > % > > Let me explain what transpired from an input perspective: > > 1. Ran bsdgrep -r "-2011" . > 2. Pressed Ctrl-Z > 3. Typed bg > 4. Typed "q" 20 times in a row exactly > 5. Pressed Ctrl-C > 6. Typed "fg" and pressed Enter > 7. Typed "ffgg" and pressed Enter > 8. Pressed Ctrl-Z and Enter > 9. Pressed Ctrl-C > > What's going on here? Where is the famous "Suspended (tty input)"? It > gets more interesting. Here's another one: > > % bsdgrep -r "-2011" . > ^Z > Suspended > % bg > [1] bsdgrep -r -2011 . & > % g(standard input):f > fg > gfg: Command not found. > [1] + Suspended (tty input) bsdgrep -r -2011 . > % jobs > [1] + Suspended (tty input) bsdgrep -r -2011 . > % fg > bsdgrep -r -2011 . > % > > And what transpired input-wise: > > 1. Ran bsdgrep -r "-2011" . > 2. Pressed Ctrl-Z > 3. Typed bg > 4. Typed "fg" and Enter > 5. Typed "fg" again and pressed Enter > 6. Typed "jobs" and pressed Enter > 7. Typed "fg" and pressed Enter > 8. Pressed Ctrl-D > > Some facts: > > - Fully 100% reproducible > - Tested only on RELENG_9 (source from 2012/10/21) > - Happens regardless of shell (bash and csh tested; csh w/out dot files) > - Similar behaviour happens with our base system grep (GNU grep) but > sometimes it manifests itself in a weirder way > - bsdgrep and GNU grep are both in state "ttyin" when this happens > > CC'ing some folks who might have some ideas or can explain how to > troubleshoot this one. For the signal part, I believe this would be > SIGTTIN.This is reproducable with the cat(1) as well. The telling part is that the backgrounded process stays on the "ttyin" cv. The code for e.g. tty read currently is structured as follows: check for background process reading from CTTY, send SIGTTYIN loop { sleep waiting for input process input } The problem is that the SIGCONT does not remove the sleeping process from the sleep queue, so the sleep is not interrupted with error. Instead, the process is woken up later when input is available. Old tty code did the recheck for background state inside the loop after the sleep. Below is the hacky change that seemingly helped for exactly your case. New code is structured so that the fix requires big movements of blocks, e.g. even if keeping my patch, the for (;;) loops in tty_ttydisc.c no longer have any use. Hope Ed will comment. diff --git a/sys/kern/tty.c b/sys/kern/tty.c index e9c0fb6..3785e81 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -434,6 +434,7 @@ ttydev_read(struct cdev *dev, struct uio *uio, int ioflag) if (error) goto done; +check_bg: error = tty_wait_background(tp, curthread, SIGTTIN); if (error) { tty_unlock(tp); @@ -441,6 +442,8 @@ ttydev_read(struct cdev *dev, struct uio *uio, int ioflag) } error = ttydisc_read(tp, uio, ioflag); + if (error == EJUSTRETURN) + goto check_bg; tty_unlock(tp); /* @@ -462,6 +465,7 @@ ttydev_write(struct cdev *dev, struct uio *uio, int ioflag) if (error) return (error); +check_bg: if (tp->t_termios.c_lflag & TOSTOP) { error = tty_wait_background(tp, curthread, SIGTTOU); if (error) @@ -484,6 +488,8 @@ ttydev_write(struct cdev *dev, struct uio *uio, int ioflag) tp->t_flags &= ~TF_BUSY_OUT; cv_signal(&tp->t_outserwait); } + if (error == EJUSTRETURN) + goto check_bg; done: tty_unlock(tp); return (error); diff --git a/sys/kern/tty_ttydisc.c b/sys/kern/tty_ttydisc.c index 52a5df2..d8b8f53 100644 --- a/sys/kern/tty_ttydisc.c +++ b/sys/kern/tty_ttydisc.c @@ -157,7 +157,7 @@ ttydisc_read_canonical(struct tty *tp, struct uio *uio, int ioflag) error = tty_wait(tp, &tp->t_inwait); if (error) return (error); - continue; + return (EJUSTRETURN); } /* Don't send the EOF char back to userspace. */ @@ -208,6 +208,7 @@ ttydisc_read_raw_no_timer(struct tty *tp, struct uio *uio, int ioflag) error = tty_wait(tp, &tp->t_inwait); if (error) return (error); + return (EJUSTRETURN); } } @@ -256,6 +257,7 @@ ttydisc_read_raw_read_timer(struct tty *tp, struct uio *uio, int ioflag, error = tty_timedwait(tp, &tp->t_inwait, hz); if (error) return (error == EWOULDBLOCK ? 0 : error); + return (EJUSTRETURN); } return (0); @@ -301,6 +303,7 @@ ttydisc_read_raw_interbyte_timer(struct tty *tp, struct uio *uio, int ioflag) error = tty_wait(tp, &tp->t_inwait); if (error) return (error); + return (EJUSTRETURN); } return ttydisc_read_raw_read_timer(tp, uio, ioflag, oresid); @@ -539,6 +542,9 @@ ttydisc_write(struct tty *tp, struct uio *uio, int ioflag) error = EIO; goto done; } + + error = EJUSTRETURN; + goto done; } while (oblen > 0); } -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 196 bytes Desc: not available URL: <http://lists.freebsd.org/pipermail/freebsd-stable/attachments/20121023/af9be83a/attachment.sig>
Hi Kostik, 2012/10/23 Konstantin Belousov <kostikbel at gmail.com>:> This is reproducable with the cat(1) as well. The telling part is that > the backgrounded process stays on the "ttyin" cv. The code for e.g. > tty read currently is structured as follows: > check for background process reading from CTTY, send SIGTTYIN > loop { > sleep waiting for input > process input > } > The problem is that the SIGCONT does not remove the sleeping process from > the sleep queue, so the sleep is not interrupted with error. Instead, the > process is woken up later when input is available. > > Old tty code did the recheck for background state inside the loop after > the sleep.Exactly. Was just debugging this as well and came to the same conclusion. Will try to come up with a decent patch tomorrow evening. Thanks for reporting the issue! -- Ed Schouten <ed at 80386.nl>
On Tue, Oct 23, 2012 at 10:42:47PM +0200, Ed Schouten wrote:> Hi Kostik, > > 2012/10/23 Konstantin Belousov <kostikbel at gmail.com>: > > This is reproducable with the cat(1) as well. The telling part is that > > the backgrounded process stays on the "ttyin" cv. The code for e.g. > > tty read currently is structured as follows: > > check for background process reading from CTTY, send SIGTTYIN > > loop { > > sleep waiting for input > > process input > > } > > The problem is that the SIGCONT does not remove the sleeping process from > > the sleep queue, so the sleep is not interrupted with error. Instead, the > > process is woken up later when input is available. > > > > Old tty code did the recheck for background state inside the loop after > > the sleep. > > Exactly. Was just debugging this as well and came to the same > conclusion. Will try to come up with a decent patch tomorrow evening. > > Thanks for reporting the issue!No problem folks. Would you like me to file a PR for this so we can track it/for historical purposes? -- | Jeremy Chadwick jdc at koitsu.org | | UNIX Systems Administrator http://jdc.koitsu.org/ | | Mountain View, CA, US | | Making life hard for others since 1977. PGP 4BD6C0CB |
On 23 October 2012 22:40, Jeremy Chadwick <jdc at koitsu.org> wrote:> No problem folks. Would you like me to file a PR for this so we can > track it/for historical purposes?yes please -- Eitan Adler
On Tue, Oct 23, 2012 at 11:07:56PM -0400, Eitan Adler wrote:> On 23 October 2012 22:40, Jeremy Chadwick <jdc at koitsu.org> wrote: > > > No problem folks. Would you like me to file a PR for this so we can > > track it/for historical purposes? > > yes pleaseThanks Eitan -- will do! -- | Jeremy Chadwick jdc at koitsu.org | | UNIX Systems Administrator http://jdc.koitsu.org/ | | Mountain View, CA, US | | Making life hard for others since 1977. PGP 4BD6C0CB |
On Tue, Oct 23, 2012 at 08:13:55PM -0700, Jeremy Chadwick wrote:> On Tue, Oct 23, 2012 at 11:07:56PM -0400, Eitan Adler wrote: > > On 23 October 2012 22:40, Jeremy Chadwick <jdc at koitsu.org> wrote: > > > > > No problem folks. Would you like me to file a PR for this so we can > > > track it/for historical purposes? > > > > yes please > > Thanks Eitan -- will do!kern/173010 -- | Jeremy Chadwick jdc at koitsu.org | | UNIX Systems Administrator http://jdc.koitsu.org/ | | Mountain View, CA, US | | Making life hard for others since 1977. PGP 4BD6C0CB |