* crashes when setting COLUMNS=0 or 1 @ 2011-06-09 10:36 Mikael Magnusson 2012-06-26 3:38 ` Geoff Wing 0 siblings, 1 reply; 7+ messages in thread From: Mikael Magnusson @ 2011-06-09 10:36 UTC (permalink / raw) To: zsh workers To reproduce, run COLUMNS=0 and type two characters. This code in zle_refresh is where it crashes, it looks quite suspicious too. ZR_memset(p1 + nllen, zr_sp, winw - nllen); p1[winw] = zr_zr; if (nllen < winw) p1[winw + 1] = zr_zr; else p1[winw + 1] = nl[winw + 1]; The code seems to expect nllen to possibly be larger than winw, yet it passes winw - nllen to memset as the length? (which is where it crashes). I can actually get a crash with a 1-char wide window too, by just resizing the terminal and typing some characters (This doesn't happen right away, needs to fiddle around for a bit, possibly ctrl-a and type some more). At first I thought it had to be doublewidth characters, but regular ones trigger it too. Hm, but this crashes somewhere else: (gdb) bt #0 0x00007ffff74198d9 in free () from /lib64/libc.so.6 #1 0x000000000047d630 in free_colour_buffer () at prompt.c:1863 #2 0x00007ffff6aab222 in zle_free_highlight () at zle_refresh.c:374 #3 0x00007ffff6aaeb08 in zrefresh () at zle_refresh.c:1715 #4 0x00007ffff6aa1d1e in zlecore () at zle_main.c:1100 #5 0x00007ffff6aa22b5 in zleread (lp=0x6c3a98, rp=0x0, flags=3, context=0) at zle_main.c:1219 #6 0x00007ffff6aa45b5 in zle_main_entry (cmd=1, ap=0x7fffffffd290) at zle_main.c:1874 #7 0x00000000004456dd in zleentry (cmd=1) at init.c:1363 #8 0x000000000044616f in inputline () at input.c:281 #9 0x0000000000445fe6 in ingetc () at input.c:217 #10 0x000000000043b8b6 in ihgetc () at hist.c:279 #11 0x000000000044e156 in gettok () at lex.c:717 #12 0x000000000044d907 in zshlex () at lex.c:395 #13 0x000000000046aefb in parse_event () at parse.c:451 #14 0x0000000000442a9d in loop (toplevel=1, justonce=0) at init.c:132 #15 0x0000000000445be6 in zsh_main (argc=2, argv=0x7fffffffd678) at init.c:1528 #16 0x0000000000410784 in main (argc=2, argv=0x7fffffffd678) at ./main.c:93 Not sure what's going on in this case. -- Mikael Magnusson ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: crashes when setting COLUMNS=0 or 1 2011-06-09 10:36 crashes when setting COLUMNS=0 or 1 Mikael Magnusson @ 2012-06-26 3:38 ` Geoff Wing 2012-06-26 7:03 ` Bart Schaefer 0 siblings, 1 reply; 7+ messages in thread From: Geoff Wing @ 2012-06-26 3:38 UTC (permalink / raw) To: zsh workers On Thursday 2011-06-09 12:36 +0200, Mikael Magnusson output: :To reproduce, run COLUMNS=0 and type two characters. This code in :zle_refresh is where it crashes, it looks quite suspicious too. : :ZR_memset(p1 + nllen, zr_sp, winw - nllen); :p1[winw] = zr_zr; :if (nllen < winw) : p1[winw + 1] = zr_zr; :else : p1[winw + 1] = nl[winw + 1]; : :The code seems to expect nllen to possibly be larger than winw, yet it :passes winw - nllen to memset as the length? (which is where it :crashes). I believe that it's checking if nllen equals winw (which is quite valid), not that it is larger. It's been a long time since I looked at this code. :I can actually get a crash with a 1-char wide window too, by :just resizing the terminal and typing some characters (This doesn't :happen right away, needs to fiddle around for a bit, possibly ctrl-a :and type some more). At first I thought it had to be doublewidth :characters, but regular ones trigger it too. Sounds like a different bug. Old versions of Zsh never let COLUMNS be set to 0 or negative numbers. It would retain its old value if you tried since it just doesn't make sense. This behaviour should be recovered. Try % COLUMNS=-1; echo $COLUMNS -1 % (core dumped) Regards, Geoff ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: crashes when setting COLUMNS=0 or 1 2012-06-26 3:38 ` Geoff Wing @ 2012-06-26 7:03 ` Bart Schaefer 2012-06-26 7:21 ` Bart Schaefer 2012-06-26 7:30 ` Bart Schaefer 0 siblings, 2 replies; 7+ messages in thread From: Bart Schaefer @ 2012-06-26 7:03 UTC (permalink / raw) To: zsh workers On Jun 26, 1:38pm, Geoff Wing wrote: } } Old versions of Zsh never let COLUMNS be set to 0 or negative numbers. Not precisely true. Here's zsh 2.4: torch<501> COLUMNS=-1 torch<502> print $COLUMNS -1 *** glibc detected *** malloc(): memory corruption (fast): 0x0809d838 *** zsh: abort (core dumped) src/zsh } It would retain its old value if you tried since it just doesn't make } sense. This behaviour should be recovered. In 2.4, putprompt() would force columns = 80 when columns == 0, but there isn't any test I can find for columns < 0. In recent version adjustcolumns() has this: #ifdef TIOCGWINSZ if (signalled || zterm_columns <= 0) zterm_columns = shttyinfo.winsize.ws_col; else shttyinfo.winsize.ws_col = zterm_columns; #endif /* TIOCGWINSZ */ if (zterm_columns <= 0) { DPUTS(signalled, "BUG: Impossible TIOCGWINSZ cols"); zterm_columns = tccolumns > 0 ? tccolumns : 80; } This is called from adjustwinsize(), and from various bits of params.c: IPDEF5("COLUMNS", &zterm_columns, zlevar_gsu) static const struct gsu_integer zlevar_gsu = { intvargetfn, zlevarsetfn, stdunsetfn }; void zlevarsetfn(Param pm, zlong x) { zlong *p = pm->u.valptr; *p = x; if (p == &zterm_lines || p == &zterm_columns) adjustwinsize(2 + (p == &zterm_columns)); } But for some reason zlvarsetfn is never called when assigning COLUMNS, so adjustwinsize() never happens. Tracing through, COLUMNS=0 is handled by addvars() via execsimple(), which does call v->pm->gsu.i->setfn at params.c:2343 ... but that's the generic intvarsetfn, zlevarsetfn has been lost somewhere along the way. This may indicate there's a more generalized problem with the handling of parameters for which IPDEF* have assigned a custom gsu. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: crashes when setting COLUMNS=0 or 1 2012-06-26 7:03 ` Bart Schaefer @ 2012-06-26 7:21 ` Bart Schaefer 2012-06-26 7:30 ` Bart Schaefer 1 sibling, 0 replies; 7+ messages in thread From: Bart Schaefer @ 2012-06-26 7:21 UTC (permalink / raw) To: zsh workers On Jun 26, 12:03am, Bart Schaefer wrote: } } IPDEF5("COLUMNS", &zterm_columns, zlevar_gsu) Oh, for pity's sake. The definition of IPDEF5 never references the F argument. Index: Src/params.c =================================================================== RCS file: /extra/cvsroot/zsh/zsh-4.0/Src/params.c,v retrieving revision 1.48 diff -u -r1.48 params.c --- Src/params.c 20 Dec 2011 17:13:38 -0000 1.48 +++ Src/params.c 26 Jun 2012 07:18:22 -0000 @@ -315,7 +315,7 @@ IPDEF4("PPID", &ppid), IPDEF4("ZSH_SUBSHELL", &zsh_subshell), -#define IPDEF5(A,B,F) {{NULL,A,PM_INTEGER|PM_SPECIAL},BR((void *)B),GSU(varinteger_gsu),10,0,NULL,NULL,NULL,0} +#define IPDEF5(A,B,F) {{NULL,A,PM_INTEGER|PM_SPECIAL},BR((void *)B),GSU(F),10,0,NULL,NULL,NULL,0} IPDEF5("COLUMNS", &zterm_columns, zlevar_gsu), IPDEF5("LINES", &zterm_lines, zlevar_gsu), IPDEF5("OPTIND", &zoptind, varinteger_gsu), ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: crashes when setting COLUMNS=0 or 1 2012-06-26 7:03 ` Bart Schaefer 2012-06-26 7:21 ` Bart Schaefer @ 2012-06-26 7:30 ` Bart Schaefer 2012-06-26 9:33 ` Peter Stephenson 1 sibling, 1 reply; 7+ messages in thread From: Bart Schaefer @ 2012-06-26 7:30 UTC (permalink / raw) To: zsh workers On Jun 26, 12:03am, Bart Schaefer wrote: } } In recent version adjustcolumns() has this: } } #ifdef TIOCGWINSZ } if (signalled || zterm_columns <= 0) } zterm_columns = shttyinfo.winsize.ws_col; } else } shttyinfo.winsize.ws_col = zterm_columns; } #endif /* TIOCGWINSZ */ } if (zterm_columns <= 0) { } DPUTS(signalled, "BUG: Impossible TIOCGWINSZ cols"); } zterm_columns = tccolumns > 0 ? tccolumns : 80; } } } } This is called from adjustwinsize() So, interesting side-effect: If my patch for IPDEF5 is applied, then settings of COLUMNS and LINES get propagated through to the tty driver and can end up affecting the behavior of the parent shell (or anything else that's using the terminal where those values were changed), even after the shell where the assignments were made has exited. E.g. (COLUMNS=20) in a subshell will change the tty driver which will signal the parent shell which will pick up the change and set its own column width to 20. This is the only case I can think of where a parameter assigned in a subshell can behave this way. So we might want to consider carefully whether this is something we want to inject only days before a 5.0.0 release ... but we should still fix the crash somehow, so maybe there's a corresponding change needed in some other place. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: crashes when setting COLUMNS=0 or 1 2012-06-26 7:30 ` Bart Schaefer @ 2012-06-26 9:33 ` Peter Stephenson 2012-06-26 14:26 ` Bart Schaefer 0 siblings, 1 reply; 7+ messages in thread From: Peter Stephenson @ 2012-06-26 9:33 UTC (permalink / raw) To: zsh workers On Tue, 26 Jun 2012 00:30:42 -0700 Bart Schaefer <schaefer@brasslantern.com> wrote: > So, interesting side-effect: If my patch for IPDEF5 is applied, then > settings of COLUMNS and LINES get propagated through to the tty driver > and can end up affecting the behavior of the parent shell (or anything > else that's using the terminal where those values were changed), even > after the shell where the assignments were made has exited. > > E.g. (COLUMNS=20) in a subshell will change the tty driver which will > signal the parent shell which will pick up the change and set its own > column width to 20. This is the only case I can think of where a > parameter assigned in a subshell can behave this way. That's not necessarily always a problem. The parent is in case subject to such changes asynchronously via SIGWINCH. The fact that it's getting the value a different way shouldn't make matters worse in general. Where it's unhelpful is if you're setting COLUMNS not because anything has changed but as a temporary trick for some utility that tests it and truncates. Then you wouldn't want the change to propagate back. This is going to be niggling if it means these two have different effects: COLUMNS=20 ls (export COLUMNS=20; ls) since they look as if they ought to be similar. Howeve, I'm not sure what can reasonably be done. Restoring COLUMNS on exit from a subshell doesn't seem a particularly clean thing to do, but might work in most cases. -- Peter Stephenson <pws@csr.com> Software Engineer Tel: +44 (0)1223 692070 Cambridge Silicon Radio Limited Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, UK Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom More information can be found at www.csr.com. Follow CSR on Twitter at http://twitter.com/CSR_PLC and read our blog at www.csr.com/blog ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: crashes when setting COLUMNS=0 or 1 2012-06-26 9:33 ` Peter Stephenson @ 2012-06-26 14:26 ` Bart Schaefer 0 siblings, 0 replies; 7+ messages in thread From: Bart Schaefer @ 2012-06-26 14:26 UTC (permalink / raw) To: zsh workers On Jun 26, 10:33am, Peter Stephenson wrote: } Subject: Re: crashes when setting COLUMNS=0 or 1 } } On Tue, 26 Jun 2012 00:30:42 -0700 } Bart Schaefer <schaefer@brasslantern.com> wrote: } > So, interesting side-effect: If my patch for IPDEF5 is applied, then } > settings of COLUMNS and LINES get propagated through to the tty driver } > and can end up affecting the behavior of the parent shell (or anything } > else that's using the terminal where those values were changed), even } > after the shell where the assignments were made has exited. } } That's not necessarily always a problem. The parent is in case subject } to such changes asynchronously via SIGWINCH. The fact that it's getting } the value a different way shouldn't make matters worse in general. Yeah, but programs (including older versions of zsh) that don't expect the tty driver to lie about the terminal size can be very confused. (Aside: ZLE can behave incredibly badly if the actual terminal width is greater than what zterm_columns asserts, because of assumptions about what happens with auto-wrap at the margins.) } Where it's unhelpful is if you're setting COLUMNS not because anything } has changed but as a temporary trick for some utility that tests it and } truncates. Then you wouldn't want the change to propagate back. Indeed. } This is going to be niggling if it means these two have different } effects: } } COLUMNS=20 ls } (export COLUMNS=20; ls) Actually those behave exactly the same; in both cases the new COLUMNS persists after the command exits, because it has been enshrined in the terminal driver. Undoing of the "temporary" assignment in the first example does not cause an explicit re-assignment of the old value, so the driver is not reloaded. } Howeve, I'm not sure what can reasonably be done. Here's one possibility: Never poke the new COLUMNS into the tty driver. Actually we could just remove the entire #ifdef block -- it's been dead code for years because (from >= 2) has never been true, because the only place adjustwinsize(2) is referenced is via zlevarsetfn, which has never been called because of the IPDEF5 typo. On the other hand it might in the longer term (no pun intended) be useful to figure out if there are circumstances where we do want this to happen -- e.g., some assignments possibly should do it, others not, and maybe we can pass a different "from" value in those cases. Index: Src/utils.c --- Src/utils.c 2012-05-07 20:54:49.000000000 -0700 +++ Src/utils.c 2012-06-26 07:07:15.000000000 -0700 @@ -1684,11 +1684,11 @@ #ifdef TIOCGWINSZ if (interact && from >= 2 && (shttyinfo.winsize.ws_row != ttyrows || shttyinfo.winsize.ws_col != ttycols)) { /* shttyinfo.winsize is already set up correctly */ - ioctl(SHTTY, TIOCSWINSZ, (char *)&shttyinfo.winsize); + /* ioctl(SHTTY, TIOCSWINSZ, (char *)&shttyinfo.winsize); */ } #endif /* TIOCGWINSZ */ if (zleactive && resetzle) { #ifdef TIOCGWINSZ Without objection, I'll commit these two patches. ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2012-06-26 14:26 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2011-06-09 10:36 crashes when setting COLUMNS=0 or 1 Mikael Magnusson 2012-06-26 3:38 ` Geoff Wing 2012-06-26 7:03 ` Bart Schaefer 2012-06-26 7:21 ` Bart Schaefer 2012-06-26 7:30 ` Bart Schaefer 2012-06-26 9:33 ` Peter Stephenson 2012-06-26 14:26 ` Bart Schaefer
Code repositories for project(s) associated with this public inbox https://git.vuxu.org/mirror/zsh/ 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 NNTP newsgroup(s).