This is the mail archive of the cygwin@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Re: readline Bug! ;-) [was: Bash Bug! (was: Bug in rxvt2.7.2 ...)]


Well, I guess I've figured this one out...  The bug was in readline-4.3.
I'm attaching patches for both bash-2.05b-5 and readline-4.3-1 (nearly
identical).  There is a *long* description of the bug and the fix below
for those who are interested, feel free to skip.
	Igor

On Wed, 2 Oct 2002, Igor Pechtchanski wrote:

> Hey, as long as we're shifting the blame, let's shift it correctly ;-)
> Details below...
>
> On Tue, 1 Oct 2002, Jelks Cabaniss wrote:
>
> > Igor Pechtchanski wrote:
> >
> > > > > As for the Ctrl-Left, this is something odd in bash.  I
> > > > > can get the same behavior in a command window running bash,
> > > > > or even by typing Esc O c.  Bash running on Linux does not
> > > > > seem to have this problem.
> >
> > I wrote, speaking about CTRL+Left:
> >
> > > > Here it crashes rxvt, but not the bash console.  WinXP.
> >
> > > I can confirm Esc O c crashing a bash command window on Win2k SP2.
> > > Seems like Esc O <anything> kills bash...
> >
> > Ah, you're right!  CTRL+Left doesn't crash bash here, but Esc O c sends
> > it flying out the window in flames.
> >
> > /Jelks
>
> This actually seems to be a readline bug.  Bash dies with a SIGSEGV
> because of an infinite recursion in _rl_dispatch_subseq() in the readline
> library.  I've included a transcript of a gdb session below.  The keys
> pressed were '<Esc> O <space>'.  I'm going to try to debug it tomorrow,
> but if anyone more familiar with the readline library wants to take a shot
> at it earlier, it's fine with me. :-)
>
> [snip]
>
> $ gdb -nw ./bash.exe
> GNU gdb 5.0 (20010428-3)
> [snip]
> (gdb) run -i
> Starting program: ./bash.exe -i
> [snip]
> Program received signal SIGSEGV, Segmentation fault.
> 0x0045bfc7 in _rl_dispatch_subseq (key=256, map=0x10028188, got_subseq=0)
>     at readline.c:529
> 529       return _rl_dispatch_subseq (key, map, 0);
> (gdb) where
> #0  0x0045bfc7 in _rl_dispatch_subseq (key=256, map=0x10028188, got_subseq=0)
>     at readline.c:529
> #1  0x0045bfbc in _rl_dispatch (key=256, map=0x10028188) at readline.c:529
> #2  0x0045c0a4 in _rl_dispatch_subseq (key=256, map=0x10028188, got_subseq=0)
>     at readline.c:570
> #3  0x0045bfbc in _rl_dispatch (key=256, map=0x10028188) at readline.c:529
> #4  0x0045c0a4 in _rl_dispatch_subseq (key=256, map=0x10028188, got_subseq=0)
>     at readline.c:570
> #5  0x0045bfbc in _rl_dispatch (key=256, map=0x10028188) at readline.c:529
> [ Zillions of identical frames here ]
> ---Type <return> to continue, or q <return> to quit---q
> Quit
> [snip]
> (gdb) q
> The program is running.  Exit anyway? (y or n) y
> $

Description of the bug and the fix (long and overly technical, feel free
to skip):

Readline has a mechanism for allowing two mappings where one is a prefix
of another, e.g., from .inputrc:

"ABCD": dump-variables
"A": dump-functions

The idea is that if it encounters a prefix of the longer pattern, readline
will keep reading characters until it either matches the pattern (in which
case it simply executes the mapping) or sees it diverge (in which case it
backtracks and executes the mapping for the shorter pattern, and then
reinterprets all pending characters).  Readline accomplishes that by
keeping a "default" map entry in which it stores the target of the shorter
mapping.  If it encounters a character for which there is no continuation
in the sequence, it will use this "default" entry to try to match a
shorter sequence or to backtrack.

Readline also has a special mapping called rl_do_lowercase_version, which
simply redirects the mapping to that of the lowercase letter.  This is
useful for keeping Meta-a and Meta-A in sync, but doesn't work too well if
it's the saved "default" mapping.  What readline tried to do is convert
the "default" key value to lowercase (which, of course, returned the same
value) and try to dispatch on that, which resulted in an infinite loop.

The fix is to check whether the default action is rl_do_lowercase_version,
and if it is, dispatch explicitly on the lowercase of the current key.
This is a bit kludgy, in that it actually does an extra evaluation of the
mapping, probably breaking the encapsulation, and certainly duplicating
code...  If anyone can think of a more elegant solution, I'd be happy.
If not, this'll work.

Oh, and IMO the default empty mapping created by rl_make_bare_keymap()
incorrectly set all entries for capital letters to rl_do_lowercase_version
(which is wrong for most mappings), so I fixed that in this patch as well.

Well, that's it, sorry for the rant.
	Igor
-- 
				http://cs.nyu.edu/~pechtcha/
      |\      _,,,---,,_		pechtcha@cs.nyu.edu
ZZZzz /,`.-'`'    -.  ;-;;,_		igor@watson.ibm.com
     |,4-  ) )-,_. ,\ (  `'-'		Igor Pechtchanski
    '---''(_/--'  `-'\_) fL	a.k.a JaguaR-R-R-r-r-r-.-.-.  Meow!

"Water molecules expand as they grow warmer" (C) Popular Science, Oct'02, p.51

Attachment: bash-2.05b-5.patch
Description: Text document

Attachment: readline-4.3-1.patch
Description: Text document

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]