From owner-freebsd-bugs@FreeBSD.ORG Tue Apr 17 17:50:04 2012 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id BAC83106564A for ; Tue, 17 Apr 2012 17:50:04 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id A2D878FC0A for ; Tue, 17 Apr 2012 17:50:04 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.5/8.14.5) with ESMTP id q3HHo42q003537 for ; Tue, 17 Apr 2012 17:50:04 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.5/8.14.5/Submit) id q3HHo4ni003536; Tue, 17 Apr 2012 17:50:04 GMT (envelope-from gnats) Date: Tue, 17 Apr 2012 17:50:04 GMT Message-Id: <201204171750.q3HHo4ni003536@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org From: Jeremy Chadwick Cc: Subject: Fwd: Re: Fwd: Re: bin/161739: top(1): top -b does not restore ICANON and ECHO terminal capabilities when exiting X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Jeremy Chadwick List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 17 Apr 2012 17:50:04 -0000 The following reply was made to PR bin/161739; it has been noted by GNATS. From: Jeremy Chadwick To: bug-followup@FreeBSD.org Cc: Subject: Fwd: Re: Fwd: Re: bin/161739: top(1): top -b does not restore ICANON and ECHO terminal capabilities when exiting Date: Tue, 17 Apr 2012 10:40:04 -0700 Below is an Email I sent kib@ about this problem, as he said he could not reproduce it. I spent 3 hours on this today, writing a debugging routine to print out all the internal variables and the terminal structures (termios) to find out where the problem lies. It appears that now the "-b" flag works fine, but "-a" is now broken as a result of that commit. The explanation for what's happening in the code is below. Someone just needs to figure out why is_a_terminal becomes 0 during the program's execution (printing output, etc.) because this is what causes the issue. -- | Jeremy Chadwick jdc@parodius.com | | Parodius Networking http://www.parodius.com/ | | UNIX Systems Administrator Mountain View, CA, US | | Making life hard for others since 1977. PGP 4BD6C0CB | ----- Forwarded message from Jeremy Chadwick ----- > From: Jeremy Chadwick > To: Konstantin Belousov > Date: Tue, 17 Apr 2012 10:29:33 -0700 > Subject: Re: Fwd: Re: bin/161739: top(1): top -b does not restore ICANON and ECHO terminal capabilities when exiting > > I stand partially corrected -- it looks like your change made recently > fixed the problem in the PR for the -b flag only; but now -a has the > problem. > > I wrote a debug printing routine and shoved it into top.c to look at the > results of new_settings and old_settings (termios struct), and also what > the current terminal settings are for comparison and some other internal > variables which are used to determine when/how to reset the terminal. > > There is definitely a problem. > > (10:23:01 jdc@omake) ~/usr.bin/top $ ./top -a 2>/tmp/results > > {pressed "q" after 1 iteration} > > (10:23:18 jdc@omake) ~/usr.bin/top $ (10:23:24 jdc@omake) ~/usr.bin/top $ > > {I had to type "stty icanon echo" to restore things} > > Results: > > (10:23:26 jdc@omake) ~/usr.bin/top $ cat /tmp/results > DEBUG: before init_termcap > DEBUG: is_a_terminal = 0 > DEBUG: smart_terminal = 0 > DEBUG: interactive = 2 (Maybe) > DEBUG: displays = 0 > DEBUG: old_settings: > DEBUG: c_iflag = 0x0 > DEBUG: c_oflag = 0x0 > DEBUG: c_cflag = 0x0 > DEBUG: c_lflag = 0x0 () > DEBUG: new_settings: > DEBUG: c_iflag = 0x0 > DEBUG: c_oflag = 0x0 > DEBUG: c_cflag = 0x0 > DEBUG: c_lflag = 0x0 () > DEBUG: current terminal settings: > DEBUG: c_iflag = 0x2b02 > DEBUG: c_oflag = 0x3 > DEBUG: c_cflag = 0x4b00 > DEBUG: c_lflag = 0x5cb (ECHOKE,ECHOE,ECHO,ECHOCTL,ISIG,ICANON,IEXTEN,) > ---------------------------------------- > DEBUG: after init_termcap > DEBUG: is_a_terminal = 0 > DEBUG: smart_terminal = 1 > DEBUG: interactive = 2 (Maybe) > DEBUG: displays = 0 > DEBUG: old_settings: > DEBUG: c_iflag = 0x2b02 > DEBUG: c_oflag = 0x3 > DEBUG: c_cflag = 0x4b00 > DEBUG: c_lflag = 0x5cb (ECHOKE,ECHOE,ECHO,ECHOCTL,ISIG,ICANON,IEXTEN,) > DEBUG: new_settings: > DEBUG: c_iflag = 0x0 > DEBUG: c_oflag = 0x0 > DEBUG: c_cflag = 0x0 > DEBUG: c_lflag = 0x0 () > DEBUG: current terminal settings: > DEBUG: c_iflag = 0x2b02 > DEBUG: c_oflag = 0x3 > DEBUG: c_cflag = 0x4b00 > DEBUG: c_lflag = 0x5cb (ECHOKE,ECHOE,ECHO,ECHOCTL,ISIG,ICANON,IEXTEN,) > ---------------------------------------- > DEBUG: before init_screen > DEBUG: is_a_terminal = 0 > DEBUG: smart_terminal = 1 > DEBUG: interactive = 1 (Yes) > DEBUG: displays = -1 > DEBUG: old_settings: > DEBUG: c_iflag = 0x2b02 > DEBUG: c_oflag = 0x3 > DEBUG: c_cflag = 0x4b00 > DEBUG: c_lflag = 0x5cb (ECHOKE,ECHOE,ECHO,ECHOCTL,ISIG,ICANON,IEXTEN,) > DEBUG: new_settings: > DEBUG: c_iflag = 0x0 > DEBUG: c_oflag = 0x0 > DEBUG: c_cflag = 0x0 > DEBUG: c_lflag = 0x0 () > DEBUG: current terminal settings: > DEBUG: c_iflag = 0x2b02 > DEBUG: c_oflag = 0x3 > DEBUG: c_cflag = 0x4b00 > DEBUG: c_lflag = 0x5cb (ECHOKE,ECHOE,ECHO,ECHOCTL,ISIG,ICANON,IEXTEN,) > ---------------------------------------- > DEBUG: after init_screen > DEBUG: is_a_terminal = 1 > DEBUG: smart_terminal = 1 > DEBUG: interactive = 1 (Yes) > DEBUG: displays = -1 > DEBUG: old_settings: > DEBUG: c_iflag = 0x2b02 > DEBUG: c_oflag = 0x3 > DEBUG: c_cflag = 0x4b00 > DEBUG: c_lflag = 0x5cb (ECHOKE,ECHOE,ECHO,ECHOCTL,ISIG,ICANON,IEXTEN,) > DEBUG: new_settings: > DEBUG: c_iflag = 0x2b02 > DEBUG: c_oflag = 0x3 > DEBUG: c_cflag = 0x4b00 > DEBUG: c_lflag = 0x4c3 (ECHOKE,ECHOE,ECHOCTL,ISIG,IEXTEN,) > DEBUG: current terminal settings: > DEBUG: c_iflag = 0x2b02 > DEBUG: c_oflag = 0x3 > DEBUG: c_cflag = 0x4b00 > DEBUG: c_lflag = 0x4c3 (ECHOKE,ECHOE,ECHOCTL,ISIG,IEXTEN,) > ---------------------------------------- > DEBUG: within quit(), before end_screen > DEBUG: is_a_terminal = 0 > DEBUG: smart_terminal = 1 > DEBUG: interactive = 1 (Yes) > DEBUG: displays = -1 > DEBUG: old_settings: > DEBUG: c_iflag = 0x2b02 > DEBUG: c_oflag = 0x3 > DEBUG: c_cflag = 0x4b00 > DEBUG: c_lflag = 0x5cb (ECHOKE,ECHOE,ECHO,ECHOCTL,ISIG,ICANON,IEXTEN,) > DEBUG: new_settings: > DEBUG: c_iflag = 0x2b02 > DEBUG: c_oflag = 0x3 > DEBUG: c_cflag = 0x4b00 > DEBUG: c_lflag = 0x4c3 (ECHOKE,ECHOE,ECHOCTL,ISIG,IEXTEN,) > DEBUG: current terminal settings: > DEBUG: c_iflag = 0x2b02 > DEBUG: c_oflag = 0x3 > DEBUG: c_cflag = 0x4b00 > DEBUG: c_lflag = 0x4c3 (ECHOKE,ECHOE,ECHOCTL,ISIG,IEXTEN,) > ---------------------------------------- > DEBUG: within quit(), after end_screen > DEBUG: is_a_terminal = 0 > DEBUG: smart_terminal = 1 > DEBUG: interactive = 1 (Yes) > DEBUG: displays = -1 > DEBUG: old_settings: > DEBUG: c_iflag = 0x2b02 > DEBUG: c_oflag = 0x3 > DEBUG: c_cflag = 0x4b00 > DEBUG: c_lflag = 0x5cb (ECHOKE,ECHOE,ECHO,ECHOCTL,ISIG,ICANON,IEXTEN,) > DEBUG: new_settings: > DEBUG: c_iflag = 0x2b02 > DEBUG: c_oflag = 0x3 > DEBUG: c_cflag = 0x4b00 > DEBUG: c_lflag = 0x4c3 (ECHOKE,ECHOE,ECHOCTL,ISIG,IEXTEN,) > DEBUG: current terminal settings: > DEBUG: c_iflag = 0x2b02 > DEBUG: c_oflag = 0x3 > DEBUG: c_cflag = 0x4b00 > DEBUG: c_lflag = 0x4c3 (ECHOKE,ECHOE,ECHOCTL,ISIG,IEXTEN,) > ---------------------------------------- > > Based on this, you can see that the tcsetattr() call to restore the > terminal from old_settings isn't happening. That call is done in > end_screen(). > > The conditional for that to happen or not is based on the is_a_terminal > variable. And as you can see, is_a_terminal is 0 when end_screen() > is called. > > You can see that is_a_terminal == 1 after init_screen() is called, > but within quit() (but before end_screen()) somehow is_a_terminal > is getting reset to 0. This is what causes the problem. > > If you want the patch to see the debug info, let me know. > > -- > | Jeremy Chadwick jdc@parodius.com | > | Parodius Networking http://www.parodius.com/ | > | UNIX Systems Administrator Mountain View, CA, US | > | Making life hard for others since 1977. PGP 4BD6C0CB | > > On Tue, Apr 17, 2012 at 08:28:36AM -0700, Jeremy Chadwick wrote: > > (08:22:23 jdc@omake) ~ $ egrep -r -n '(ICANON|ECHO)' /usr/src/contrib/top > > /usr/src/contrib/top/screen.c:250: new_settings.sg_flags &= ~(ECHO|XTABS); > > /usr/src/contrib/top/screen.c:278: /* turn off ICANON, character echo and tab expansion */ > > /usr/src/contrib/top/screen.c:279: new_settings.c_lflag &= ~(ICANON|ECHO); > > /usr/src/contrib/top/screen.c:302: /* turn off ICANON, character echo and tab expansion */ > > /usr/src/contrib/top/screen.c:303: new_settings.c_lflag &= ~(ICANON|ECHO); > > > > So it looks to me like these capabilities aren't being restored > > prior to top exiting. It used to be this way with just "-b", but > > now affects "-a" as well. > > > > All of those lines are part of init_screen(). However this routine > > is filled with #ifdefs. > > > > end_screen() has some generic attempt to reset these capabilities > > (variable is called old_settings. > > > > Possibly the issue is with some kind of code logic bug pertaining to > > is_a_terminal or smart_terminal. > > > > -- > > | Jeremy Chadwick jdc@parodius.com | > > | Parodius Networking http://www.parodius.com/ | > > | UNIX Systems Administrator Mountain View, CA, US | > > | Making life hard for others since 1977. PGP 4BD6C0CB | > > > > On Tue, Apr 17, 2012 at 08:19:29AM -0700, Jeremy Chadwick wrote: > > > On Tue, Apr 17, 2012 at 12:36:38PM +0300, Konstantin Belousov wrote: > > > > On Mon, Apr 16, 2012 at 02:48:33PM -0700, Jeremy Chadwick wrote: > > > > > Kostik, > > > > > > > > > > Please see the below PR. I believe you've introduced a problem that > > > > > used to just affect the -b flag, but now affects -a as well. > > > > > > > > > > Maybe you can fix both. :-) > > > > I cannot reproduce the problem. > > > > > > On what, RELENG_9 or what? This is easily reproducible on every > > > RELENG_8 system we have, as well as my home workstation, and a RELENG_8 > > > FreeBSD instance run under VMware. > > > > > > (08:16:25 jdc@omake) ~ $ stty -a > > > speed 9600 baud; 43 rows; 132 columns; > > > lflags: icanon isig iexten echo echoe -echok echoke -echonl echoctl > > > -echoprt -altwerase -noflsh -tostop -flusho -pendin -nokerninfo > > > -extproc > > > iflags: -istrip icrnl -inlcr -igncr ixon -ixoff ixany imaxbel -ignbrk > > > brkint -inpck -ignpar -parmrk > > > oflags: opost onlcr -ocrnl tab0 -onocr -onlret > > > cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow > > > -dtrflow -mdmbuf > > > cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = ; > > > eol2 = ; erase = ^?; erase2 = ^H; intr = ^C; kill = ^U; > > > lnext = ^V; min = 1; quit = ^\; reprint = ^R; start = ^Q; > > > status = ^T; stop = ^S; susp = ^Z; time = 0; werase = ^W; > > > > > > (08:16:27 jdc@omake) ~ $ top -a > > > last pid: 62310; load averages: 0.00, 0.00, 0.00 up 1+11:03:16 08:16:30 > > > 32 processes: 1 running, 31 sleeping > > > CPU: % user, % nice, % system, % interrupt, % idle > > > Mem: 168M Active, 333M Inact, 375M Wired, 236K Cache, 389M Buf, 2764M Free > > > Swap: 8192M Total, 8192M Free > > > > > > PID USERNAME THR PRI NICE SIZE RES STATE C TIME WCPU COMMAND > > > 6482 halbot 1 44 0 90940K 75900K select 0 0:14 0.00% /usr/local/bin/perl /home/halbot/hal/halbot.pl /home/halbot/ > > > 575 root 1 44 0 6900K 1272K select 0 0:06 0.00% /usr/sbin/powerd > > > 19810 root 1 44 0 73092K 43876K select 0 0:04 0.00% /usr/local/bin/spamd -c --min-children=4 --min-spare=4 --max > > > 572 root 1 44 0 11788K 2560K select 0 0:02 0.00% /usr/sbin/ntpd -c /conf/ME/ntp.conf -p /var/run/ntpd.pid -f > > > 362 _pflogd 1 44 0 8116K 1676K bpf 0 0:01 0.00% pflogd: [running] -s 116 -i pflog0 -f /var/log/pflog (pflogd > > > 19811 root 1 44 0 75140K 46620K select 0 0:01 0.00% spamd child (perl) > > > 657 root 1 44 0 11228K 2832K kqread 2 0:01 0.00% /usr/local/libexec/postfix/master > > > 58324 root 1 44 0 10436K 2344K kqread 2 0:00 0.00% /usr/local/sbin/dovecot -c /conf/ME/mail/dovecot.conf > > > 19812 root 1 44 0 73092K 44712K select 1 0:00 0.00% spamd child (perl) > > > 672 root 1 44 0 7960K 1600K nanslp 0 0:00 0.00% /usr/sbin/cron -s > > > 493 root 1 44 0 6904K 1516K select 0 0:00 0.00% /usr/sbin/syslogd -s > > > 5912 bind 7 44 0 28836K 18248K kqread 0 0:00 0.00% /usr/sbin/named -t /var/named -u bind > > > 58325 dovecot 1 44 0 10432K 1980K kqread 0 0:00 0.00% dovecot/anvil > > > 58326 root 1 44 0 10436K 1960K kqread 1 0:00 0.00% dovecot/log > > > 663 postfix 1 44 0 11228K 2952K kqread 1 0:00 0.00% qmgr -l -t fifo -u > > > 19813 root 1 44 0 73092K 43876K select 2 0:00 0.00% spamd child (perl) > > > 19815 root 1 44 0 73092K 43876K select 3 0:00 0.00% spamd child (perl) > > > 19814 root 1 44 0 73092K 43876K select 2 0:00 0.00% spamd child (perl) > > > 62304 root 1 45 0 18980K 4048K sbwait 2 0:00 0.00% sshd: jdc [priv] (sshd) > > > 62302 root 1 45 0 12676K 2544K kqread 0 0:00 0.00% dovecot/auth -w > > > 62300 dovecot 1 44 0 12640K 2480K kqread 3 0:00 0.00% dovecot/auth > > > 668 root 1 44 0 16420K 3716K select 1 0:00 0.00% /usr/sbin/sshd > > > 62307 jdc 1 44 0 10228K 2868K wait 1 0:00 0.00% -bash (bash) > > > 62299 root 1 44 0 10432K 2900K kqread 1 0:00 0.00% dovecot/config > > > 62306 jdc 1 44 0 18980K 4132K select 1 0:00 0.00% sshd: jdc@pts/0 (sshd) > > > 62309 postfix 1 44 0 11232K 2984K kqread 0 0:00 0.00% pickup -l -t fifo -u > > > 62301 root 1 44 0 13124K 2644K kqread 0 0:00 0.00% dovecot/ssl-params > > > 62310 jdc 1 44 0 9356K 2084K CPU0 0 0:00 0.00% top -a > > > 702 root 1 44 0 9008K 1636K select 1 0:00 0.00% /usr/sbin/inetd -C 0 > > > 360 root 1 76 0 8116K 1636K sbwait 1 0:00 0.00% pflogd: [priv] (pflogd) > > > 721 root 1 76 0 6900K 1268K ttyin 1 0:00 0.00% /usr/libexec/getty Pc ttyv0 > > > 722 root 1 76 0 6900K 1268K ttyin 0 0:00 0.00% /usr/libexec/getty Pc ttyv1 > > > > > > > > > > > > (08:16:31 jdc@omake) ~ $ speed 9600 baud; 43 rows; 132 columns; > > > lflags: -icanon isig iexten -echo echoe -echok echoke -echonl echoctl > > > -echoprt -altwerase -noflsh -tostop -flusho -pendin -nokerninfo > > > -extproc > > > iflags: -istrip icrnl -inlcr -igncr ixon -ixoff ixany imaxbel -ignbrk > > > brkint -inpck -ignpar -parmrk > > > oflags: opost onlcr -ocrnl tab0 -onocr -onlret > > > cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow > > > -dtrflow -mdmbuf > > > cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = ; > > > eol2 = ; erase = ^?; erase2 = ^H; intr = ^C; kill = ^U; > > > lnext = ^V; min = 1; quit = ^\; reprint = ^R; start = ^Q; > > > status = ^T; stop = ^S; susp = ^Z; time = 0; werase = ^W; > > > > > > > > > All I did was hit "q" to exit top, then typed "stty -a". None of my > > > input was echo'd back to the terminal, which is why you seed the "speed > > > 9600 baud ..." on the same line as my shell. > > > > > > Note the -icanon and -echo capabilities shown there, while prior to > > > running top, they aren't "-" (meaning icanon and echo are enabled). > > > > > > -- > > > | Jeremy Chadwick jdc@parodius.com | > > > | Parodius Networking http://www.parodius.com/ | > > > | UNIX Systems Administrator Mountain View, CA, US | > > > | Making life hard for others since 1977. PGP 4BD6C0CB | > > > ----- End forwarded message -----