Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: [PATCH] allocate origline by ztrdup(), not by dupstring()

2015/06/17 01:54, Oliver Kiddle <okiddle@xxxxxxxxxxx> wrote:

> it seems to always be the case
> that origline == u->origline before this block runs. So it is copying freed
> memory. I tried the obvious change of checking that condition first but
> that seems to result in deleted characters being treated as if they were
> part of the original string before completion.

Yes, my patch is obviously wrong here. I guess the problem is that, near
line 2683 of complist.c, the value of origline is saved in s->origline,
but the memory pointed to by origline will be zsfree'ed while s->origline
is still pointing to the memory.

> It is also calling zsfree
> on origline before ther very first time that it is initialised.

Initially origline is NULL, and zsfree() will do nothing for that case.

> I think it might be easier to approach this by revisiting the original
> problem. I've tried binding a widget direct to menuselect but haven't
> been able to get anything odd to happen.

I can't remember exactly what was the problem I was trying to solve.
But if I checkout the commit b11f7a7e3028420d027e71713d5ec1cae0451fbb
(i.e., revert my patch), then I have the following problem (Mac OS X 10.9.5):

$ ~/test/bin/zsh -f             # zsh-5.0.7-194-gb11f7a7
% modload zsh/complist
% autoload -U compinit
% compinit
% bindkey '^K' menu-select
% bindkey -M menuselect '^E' vi-insert
% mkdir tmp && cd tmp
% touch foo bar boo
% ls <TAB><TAB><ctrl-K><ctrl-E>

and the command line is not updated correctly.

In gdb attached to the above zsh, after 'ls <TAB><TAB>',

(gdb) print origline
$12 = 0x7fc412802870 "ls "
(gdb) print *(char*)0x7fc412802873    # 0x7fc412802870 + 3
$13 = 0 '\0'

then I set a watchpoint at 0x7fc412802873 as

(gdb) watch *(char*)0x7fc412802873
(gdb) cont

and hit <ctrl-K> in the zsh gives:

Hardware watchpoint 4: *(char *) 140480100706419   # = 0x7fc412802873

Old value = 0 '\0'
New value = 98 'b'
0x00007fff8bd9e042 in _platform_memmove$VARIANT$Nehalem ()
(gdb) print origline
$4 = 0x7fc412802870 "ls bo"          # address has not changed
(gdb) bt
#0  0x00007fff8bd9e042 in _platform_memmove$VARIANT$Nehalem ()
#1  0x00007fff908577e3 in stpcpy ()
#2  0x00007fff908c5a44 in __strcpy_chk ()
#3  0x000000010975ec49 in dupstring (s=0x7fc411c29ba0 "ls bar") at string.c:40
#4  0x00000001099246e4 in domenuselect (dummy=0x0, dat=0x0) at complist.c:2551
#5  0x0000000109922f78 in menuselect (args=0x1098bae60) at complist.c:3428
#6  0x0000000109899b36 in completecall (args=0x1098bae60) at zle_tricky.c:208
#7  0x0000000109883919 in execzlefunc (func=0x7fc411c04d20, args=0x1098bae60, set_bindk=0) at zle_main.c:1345
#8  0x0000000109883454 in zlecore () at zle_main.c:1066
#9  0x00000001098844ba in zleread (lp=0x109797ad0, rp=0x0, flags=3, context=0, init=0x1098b23c8 "zle-line-init", finish=0x1098b23d6 "zle-line-finish") at zle_main.c:1253
#10 0x00000001098851bb in zle_main_entry (cmd=1, ap=0x7fff5653c690) at zle_main.c:1914

So the memory pointed to by origline (0x7fc412802870 ...) seems to be
reused by dupstring(). Does this mean that the heap in which origline
is allocated is popped somewhere?

I'm quite busy now and may not have time to go into any more detail
at least for a few days. Sorry.


Messages sorted by: Reverse Date, Date, Thread, Author