Dominique Pelle wrote:

> 2008/12/16 Bram Moolenaar <b...@moolenaar.net>:
> >
> >
> > Matt Wozniski wrote:
> >
> >> function! ReturnArgs(...)
> >>   return a:000
> >> endfunction
> >>
> >> " Seems to work fine?
> >> echo ReturnArgs(1, 2, 3)
> >>
> >> " SEGV
> >> echo string(ReturnArgs(1, 2, 3))
> >>
> >> function! MakeArgsDict(...)
> >>   return { 'args': a:000 }
> >> endfunction
> >>
> >> " E685 Internal Error
> >> echo MakeArgsDict(1, 2, 3)
> >>
> >> " SEGV
> >> echo string(MakeArgsDict(1, 2, 3))
> >
> > For it crashes a while after trying these things.  Most likely the
> > reference count for a:000 is wrong.  Never thought of someone returning
> > it...
> 
> When I debugged, I found that v_list was pointing to an invalid address,
> which had been set in call_user_func() to &fc.l_varlist;  This variable is
> in the stack and was only valid while in call_user_func() and the functions it
> may calls.  Somehow, a list still refers to this address after returning from
> call_user_func() so v_list points then to an invalid address.
> 
> Making variable fc static (in function call_user_func()) avoids using an
> invalid address and thus avoids a crash, but it's still not the right way
> to fix it.
> 
> > " Seems to work fine?
> > echo ReturnArgs(1, 2, 3)
> 
> Actually, even though this appears to work, valgrind memory checker
> already sees a problem there:
> 
> ==23275== Invalid read of size 4
> ==23275==    at 0x809C577: echo_string (eval.c:7232)
> ==23275==    by 0x80AD48C: ex_echo (eval.c:19481)
> ==23275==    by 0x80C71C6: do_one_cmd (ex_docmd.c:2622)
> ==23275==    by 0x80C4A46: do_cmdline (ex_docmd.c:1096)
> ==23275==    by 0x8149D7A: nv_colon (normal.c:5233)
> ==23275==    by 0x81433FE: normal_cmd (normal.c:1200)
> ==23275==    by 0x810678D: main_loop (main.c:1180)
> ==23275==    by 0x81062DA: main (main.c:939)
> ==23275==  Address 0xbef5e280 is not stack'd, malloc'd or (recently) free'd
> ==23275==
> ==23275== Invalid write of size 4
> ==23275==    at 0x809C59D: echo_string (eval.c:7239)
> ==23275==    by 0x80AD48C: ex_echo (eval.c:19481)
> ==23275==    by 0x80C71C6: do_one_cmd (ex_docmd.c:2622)
> ==23275==    by 0x80C4A46: do_cmdline (ex_docmd.c:1096)
> ==23275==    by 0x8149D7A: nv_colon (normal.c:5233)
> ==23275==    by 0x81433FE: normal_cmd (normal.c:1200)
> ==23275==    by 0x810678D: main_loop (main.c:1180)
> ==23275==    by 0x81062DA: main (main.c:939)
> ==23275==  Address 0xbef5e280 is not stack'd, malloc'd or (recently) free'd
> 
> (etc, more errors to follow)
> 
> Line eval.c:7232 is:
> 
>  7232             else if (copyID != 0 && tv->vval.v_list->lv_copyID == 
> copyID)
>  7233             {
>  7234                 *tofree = NULL;
>  7235                 r = (char_u *)"[...]";
>  7236             }
> 
> 'tv->vval.v_list' points to the invalid address which set as there
> at line 21193:
> 
> 21191     v->di_tv.v_type = VAR_LIST;
> 21192     v->di_tv.v_lock = VAR_FIXED;
> 21193     v->di_tv.vval.v_list = &fc.l_varlist;
> 
> (fc being a local var in the stack)

What is happening here is that a few things are put on the stack to
avoid malloc()/free() calls.  These are quite expensive and adds
overhead to every function call.

The reference count of these are not used.  When the function returns,
the items automatically disappear.  That's a bit of a problem if you
return the value or assigned it to a global variable.

I think the only proper solution is to do that malloc()/free().
Not only for a:000, but also for l: and a:.  And all elements
contained in them, that's going to be time consuming.

Another method would be to disallow passing these dictionaries to
outside the function scope.  One would have to make a copy instead.
Checking for this may be complicated though.  And this also doesn't
solve the problem for variables such as a:firstline that are also on the
stack.

It looks like the best solution is to put the whole funccall_T in
allocated memory.  And only free it when all the reference counts are
back to zero.  Need to make a list of them and add some code to the
garbage collector.

-- 
ARTHUR:          But if he was dying, he wouldn't bother to carve
                 "Aaaaarrrrrrggghhh".  He'd just say it.
BROTHER MAYNARD: It's down there carved in stone.
GALAHAD:         Perhaps he was dictating.
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

 /// Bram Moolenaar -- b...@moolenaar.net -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\        download, build and distribute -- http://www.A-A-P.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Raspunde prin e-mail lui