Fwd: Re: Fwd: Re: bin/161739: top(1): top -b does not restore ICANON
and ECHO terminal capabilities when exiting
Jeremy Chadwick
freebsd at jdc.parodius.com
Tue Apr 17 17:50:04 UTC 2012
The following reply was made to PR bin/161739; it has been noted by GNATS.
From: Jeremy Chadwick <freebsd at jdc.parodius.com>
To: bug-followup at 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 at 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 <freebsd at jdc.parodius.com> -----
> From: Jeremy Chadwick <freebsd at jdc.parodius.com>
> To: Konstantin Belousov <kostikbel at gmail.com>
> 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 at omake) ~/usr.bin/top $ ./top -a 2>/tmp/results
>
> {pressed "q" after 1 iteration}
>
> (10:23:18 jdc at omake) ~/usr.bin/top $ (10:23:24 jdc at omake) ~/usr.bin/top $
>
> {I had to type "stty icanon echo" to restore things}
>
> Results:
>
> (10:23:26 jdc at 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 at 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 at 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 at 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 at 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 = <undef>;
> > > eol2 = <undef>; 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 at 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 at 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 at 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 = <undef>;
> > > eol2 = <undef>; 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 at 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 -----
More information about the freebsd-bugs
mailing list