Re: Bug: E685, SEGV - a:000 garbage collected too early?

2008-12-18 Fir de Conversatie Dominique Pelle

Bram Moolenaar skribis:

  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...

 [...]

 I have made a patch to fix this.  It's complicated stuff, I hope I
 thought of everything that could possibly go wrong, including memory
 leaks.

 Dominique, can you try including the patch and running valgrind?  And
 check for memory leaks?


It looks good to me.  Patch fixes the bug and I can't see any error
or leak with valgrind memory checker.  I tried all test cases reported
by Matt Wozniski, as well as make test (all tests passed).

-- Dominique

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



Re: Bug: E685, SEGV - a:000 garbage collected too early?

2008-12-18 Fir de Conversatie Bram Moolenaar


Dominique Pelle wrote:

 Bram Moolenaar skribis:
 
   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...
 
  [...]
 
  I have made a patch to fix this.  It's complicated stuff, I hope I
  thought of everything that could possibly go wrong, including memory
  leaks.
 
  Dominique, can you try including the patch and running valgrind?  And
  check for memory leaks?
 
 
 It looks good to me.  Patch fixes the bug and I can't see any error
 or leak with valgrind memory checker.  I tried all test cases reported
 by Matt Wozniski, as well as make test (all tests passed).

Thanks for checking this.  I'll have last look at it and send it out
soon.

-- 
ARTHUR:  No, hang on!  Just answer the five questions ...
GALAHAD: Three questions ...
ARTHUR:  Three questions ...  And we shall watch ... and pray.
 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
-~--~~~~--~~--~--~---



Re: Bug: E685, SEGV - a:000 garbage collected too early?

2008-12-17 Fir de Conversatie Bram Moolenaar


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
 Arrggghhh.  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
-~--~~~~--~~--~--~---



Re: Bug: E685, SEGV - a:000 garbage collected too early?

2008-12-17 Fir de Conversatie Bram Moolenaar


Tony Mechelynck wrote:

 On 17/12/08 13:34, Bram Moolenaar wrote:
 
  Dominique Pelle wrote:
 
  2008/12/16 Bram Moolenaarb...@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() tofc.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.
 
 When returning a Number (e.g. :return a:lastline) or a Float, I 
 suppose the return method guarantees that there'll be no problem. I'm 
 less certain about returning a String variable local to the function, 
 but I suppose existing code already provides for that. A Funcref to a 
 function defined inside the function should remain valid -- or does it? 
 But what we're talking about here is when the returned object is a List 
 or Dictionary containing (at any level of depth) something local to the 
 function, which would disappear at return-time. (Returning a pointer to 
 a _global_ List or Dictionary ought to be no problem if no local 
 elements or sub-elements have been added by the function.)

This only matters for a:000, l: and a:.  These are allocated on the
stack.  All other things are in allocated memory and can be passed
around without problems.

 Proposed solution: returning a List or 

Re: Bug: E685, SEGV - a:000 garbage collected too early?

2008-12-17 Fir de Conversatie Bram Moolenaar


  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...

[...]

I have made a patch to fix this.  It's complicated stuff, I hope I
thought of everything that could possibly go wrong, including memory
leaks.

Dominique, can you try including the patch and running valgrind?  And
check for memory leaks?


*** ../vim-7.2.069/src/eval.c   Tue Dec  9 10:56:50 2008
--- src/eval.c  Wed Dec 17 21:32:26 2008
***
*** 32,37 
--- 32,40 
  
  #define DICT_MAXNEST 100  /* maximum nesting of lists and dicts */
  
+ #define DO_NOT_FREE_CNT 9 /* refcount for dict or list that should not
+  be freed. */
+ 
  /*
   * In a hashtab item hi_key points to di_key in a dictitem.
   * This avoids adding a pointer to the hashtab item.
***
*** 789,794 
--- 792,799 
  static void func_unref __ARGS((char_u *name));
  static void func_ref __ARGS((char_u *name));
  static void call_user_func __ARGS((ufunc_T *fp, int argcount, typval_T 
*argvars, typval_T *rettv, linenr_T firstline, linenr_T lastline, dict_T 
*selfdict));
+ static int can_free_funccal __ARGS((funccall_T *fc, int copyID)) ;
+ static void free_funccal __ARGS((funccall_T *fc, int free_val));
  static void add_nr_var __ARGS((dict_T *dp, dictitem_T *v, char *name, 
varnumber_T nr));
  static win_T *find_win_by_nr __ARGS((typval_T *vp, tabpage_T *tp));
  static void getwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off));
***
*** 923,928 
--- 928,937 
  /* pointer to funccal for currently active function */
  funccall_T *current_funccal = NULL;
  
+ /* pointer to list of previously used funccal, still around because some
+  * item in it is still being used. */
+ funccall_T *previous_funccal = NULL;
+ 
  /*
   * Return TRUE when a function was ended by a :return command.
   */
***
*** 6490,6496 
  buf_T *buf;
  win_T *wp;
  int   i;
! funccall_T*fc;
  int   did_free = FALSE;
  #ifdef FEAT_WINDOWS
  tabpage_T *tp;
--- 6499,6505 
  buf_T *buf;
  win_T *wp;
  int   i;
! funccall_T*fc, **pfc;
  int   did_free = FALSE;
  #ifdef FEAT_WINDOWS
  tabpage_T *tp;
***
*** 6574,6579 
--- 6583,6602 
else
ll = ll-lv_used_next;
  
+ /* check if any funccal can be freed now */
+ for (pfc = previous_funccal; *pfc != NULL; )
+ {
+   if (can_free_funccal(*pfc, copyID))
+   {
+   fc = *pfc;
+   *pfc = fc-caller;
+   free_funccal(fc, TRUE);
+   did_free = TRUE;
+   }
+   else
+   pfc = (*pfc)-caller;
+ }
+ 
  return did_free;
  }
  
***
*** 18962,18968 
  dictitem_T*dict_var;
  {
  hash_init(dict-dv_hashtab);
! dict-dv_refcount = 9;
  dict_var-di_tv.vval.v_dict = dict;
  dict_var-di_tv.v_type = VAR_DICT;
  dict_var-di_tv.v_lock = VAR_FIXED;
--- 18985,18991 
  dictitem_T*dict_var;
  {
  hash_init(dict-dv_hashtab);
! dict-dv_refcount = DO_NOT_FREE_CNT;
  dict_var-di_tv.vval.v_dict = dict;
  dict_var-di_tv.v_type = VAR_DICT;
  dict_var-di_tv.v_lock = VAR_FIXED;
***
*** 19299,19304 
--- 19322,19329 
   * Copy the values from typval_T from to typval_T to.
   * When needed allocates string or increases reference count.
   * Does not make a copy of a list or dict but copies the reference!
+  * It is OK for from and to to point to the same item.  This is used to
+  * make a copy later.
   */
  static void
  copy_tv(from, to)
***
*** 2,21117 
  char_u*save_sourcing_name;
  linenr_T  save_sourcing_lnum;
  scid_Tsave_current_SID;
! funccall_Tfc;
  int   save_did_emsg;
  static intdepth = 0;
  dictitem_T*v;
--- 21136,21142 
  char_u*save_sourcing_name;
  linenr_T  save_sourcing_lnum;
  scid_Tsave_current_SID;
! funccall_T*fc;
  int   save_did_emsg;
  static intdepth = 0;
  dictitem_T*v;
***
*** 21137,21172 
  
  line_breakcheck();/* check for CTRL-C hit */
  
! fc.caller = current_funccal;
! current_funccal = fc;
! fc.func = fp;
! fc.rettv = rettv;
  rettv-vval.v_number = 0;
! fc.linenr = 0;
! fc.returned = FALSE;
! fc.level = ex_nesting_level;
  /* Check 

Re: Bug: E685, SEGV - a:000 garbage collected too early?

2008-12-16 Fir de Conversatie Bram Moolenaar


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...

-- 
MONK: ... and the Lord spake, saying, First shalt thou take out the Holy Pin,
  then shalt thou count to three, no more, no less.  Three shalt be the
  number thou shalt count, and the number of the counting shalt be three.
  Four shalt thou not count, neither count thou two, excepting that thou
  then proceed to three.  Five is right out.  Once the number three, being
  the third number, be reached, then lobbest thou thy Holy Hand Grenade of
  Antioch towards thou foe, who being naughty in my sight, shall snuff it.
 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
-~--~~~~--~~--~--~---



Re: Bug: E685, SEGV - a:000 garbage collected too early?

2008-12-16 Fir de Conversatie Dominique Pelle

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)

-- Dominique

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



Bug: E685, SEGV - a:000 garbage collected too early?

2008-12-15 Fir de Conversatie Matt Wozniski

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))

~Matt

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



Re: Bug: E685, SEGV - a:000 garbage collected too early?

2008-12-15 Fir de Conversatie Dominique Pelle

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))

 ~Matt


I can reproduce that with vim-7.2.69 on Linux.

Following patch seems to fix it, but I'm not sure whether
that's the correct fix or whether it's only a workaround:

$ cvs diff -c eval.c
Index: eval.c
===
RCS file: /cvsroot/vim/vim7/src/eval.c,v
retrieving revision 1.277
diff -c -r1.277 eval.c
*** eval.c  9 Dec 2008 09:57:49 -   1.277
--- eval.c  15 Dec 2008 19:39:37 -
***
*** 2,21117 
  char_u*save_sourcing_name;
  linenr_T  save_sourcing_lnum;
  scid_Tsave_current_SID;
! funccall_Tfc;
  int   save_did_emsg;
  static intdepth = 0;
  dictitem_T*v;
--- 2,21117 
  char_u*save_sourcing_name;
  linenr_T  save_sourcing_lnum;
  scid_Tsave_current_SID;
! static funccall_T fc;
  int   save_did_emsg;
  static intdepth = 0;
  dictitem_T*v;


-- Dominique

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



Re: Bug: E685, SEGV - a:000 garbage collected too early?

2008-12-15 Fir de Conversatie Matt Wozniski

On Mon, Dec 15, 2008 at 2:42 PM, Dominique Pelle wrote:

 Matt Wozniski wrote:

 function! ReturnArgs(...)
  return a:000
 endfunction

 function! MakeArgsDict(...)
  return { 'args': a:000 }
 endfunction

 I can reproduce that with vim-7.2.69 on Linux.

 Following patch seems to fix it, but I'm not sure whether
 that's the correct fix or whether it's only a workaround:

That's slightly better, since it no longer seems to crash, but it's
still wrong.  With that patch applied, combining those two functions -
eg,

:echo MakeArgsDict(ReturnArgs(1, 2, 3))

gives the completely nonsensical result

{'args': [[...]]}

when the correct result should be

{'args': [1, 2, 3]}

Still haven't looked at the source, though, so I can't suggest a
better patch yet.

~Matt

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



Re: Bug: E685, SEGV - a:000 garbage collected too early?

2008-12-15 Fir de Conversatie Matt Wozniski

On Mon, Dec 15, 2008 at 4:49 PM, Matt Wozniski wrote:
 On Mon, Dec 15, 2008 at 2:42 PM, Dominique Pelle wrote:

 Matt Wozniski wrote:

 function! ReturnArgs(...)
  return a:000
 endfunction

 function! MakeArgsDict(...)
  return { 'args': a:000 }
 endfunction

 I can reproduce that with vim-7.2.69 on Linux.

 Following patch seems to fix it, but I'm not sure whether
 that's the correct fix or whether it's only a workaround:

 That's slightly better, since it no longer seems to crash, but it's
 still wrong.  With that patch applied, combining those two functions -
 eg,

 :echo MakeArgsDict(ReturnArgs(1, 2, 3))

 gives the completely nonsensical result

 {'args': [[...]]}

 when the correct result should be

 {'args': [1, 2, 3]}

 Still haven't looked at the source, though, so I can't suggest a
 better patch yet.

Better still,

:echo string(MakeArgsDict(ReturnArgs(1, 2, 3)))

gives

E724: variable nested too deep for displaying
{'args': }

~Matt

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