Loading ...
Sorry, an error occurred while loading the content.
 

Re: Fix for crash in eval.c

Expand Messages
  • Dominique Pellé
    ... I tried to fix the leak as well but without success so far. It does not seem simple. In any cases, it s a real leak, running the following leak.vim script
    Message 1 of 12 , May 3, 2009
      Nico Weber wrote:

      > Hi,
      >
      > On 03.05.2009, at 00:03, Dominique Pellé wrote:
      >
      >> After applying your patch, there are no such errors anymore.
      >>
      >> However, when exiting, I see that those blocks are not being
      >> freed:
      >>
      >> ==16990== 217 bytes in 10 blocks are possibly lost in loss record 36
      >> of 57
      >> ==16990==    at 0x402603E: malloc (vg_replace_malloc.c:207)
      >> ==16990==    by 0x81142FA: lalloc (misc2.c:866)
      >> ==16990==    by 0x8114216: alloc (misc2.c:765)
      >> ==16990==    by 0x807AD1D: dictitem_alloc (eval.c:6775)
      >> ==16990==    by 0x8074FFD: set_var_lval (eval.c:2856)
      >> ==16990==    by 0x80742F4: ex_let_one (eval.c:2414)
      >> ==16990==    by 0x807329F: ex_let_vars (eval.c:1869)
      >> ==16990==    by 0x8073250: ex_let (eval.c:1834)
      >> ==16990==    by 0x80A6AA3: do_one_cmd (ex_docmd.c:2622)
      >> ==16990==    by 0x80A4323: do_cmdline (ex_docmd.c:1096)
      >> ==16990==    by 0x8090328: call_user_func (eval.c:21301)
      >> ==16990==    by 0x807C4FE: call_func (eval.c:8079)
      >> ==16990==    by 0x807C142: get_func_tv (eval.c:7925)
      >> ==16990==    by 0x8075B83: ex_call (eval.c:3333)
      >> ==16990==    by 0x80A6AA3: do_one_cmd (ex_docmd.c:2622)
      >> ==16990==    by 0x80A4323: do_cmdline (ex_docmd.c:1096)
      >> ==16990==    by 0x812A758: nv_colon (normal.c:5227)
      >> ==16990==    by 0x8123DA2: normal_cmd (normal.c:1189)
      >> ==16990==    by 0x80E6D49: main_loop (main.c:1180)
      >> ==16990==    by 0x80E6896: main (main.c:939)
      >>
      >> I built Vim with -DEXITFREE (i.e. uncommented line
      >> PROFILE_CFLAGS = -DEXITFREE  in src/Makefile)
      >> so normally all blocks should be freed when exiting.
      >
      > Thanks for checking.
      >
      > I've attached an updated version of the patch that fixes some of the
      > leaks. The copy()d dicts in the script don't get freed, but I don't
      > (yet?) understand why.
      >
      > Nico


      I tried to fix the leak as well but without success so far.
      It does not seem simple.

      In any cases, it's a real leak, running the following leak.vim
      script for example causes Vim memory usage to grow
      continuously:

      --- 8< --- cut here --- 8< --- cut here --- 8< ---
      set nocp

      " foo.vim is the script attached in the original bug submission
      " at http://groups.google.com/group/vim_mac/browse_thread/thread/4e0149ff4f84e3d3
      so foo.vim

      let g:count_loops = 0
      while 1
      call foo#Buffer.New()
      q
      let g:count_loops = g:count_loops + 1
      endwhile
      --- 8< --- cut here --- 8< --- cut here --- 8< ---

      I do:

      $ vim -u NONE leak.vim
      :so %

      Then in another xterm, I can see with "top" that memory usage
      of Vim keeps increasing.

      If I run the leak.vim script with Valgrind...

      valgrind --leak-resolution=high --leak-check=yes \
      --num-callers=30 --track-fds=yes 2> vg.log \
      ./vim -u NONE leak.vim

      Then do:
      - :so %
      - let the script execute for some time
      - press CTRL-C to interrupt the infinite loop
      - Look at how many times loop iterated with
      :echo g:count_loops
      (it prints 2774 for example)
      - then quit vim: qa!

      Then look for leaks in vg.log, and observe that some leaks
      happen exactly 2774 times (same number as number as
      g:loop_count):

      ==22962== 27,740 bytes in 2,774 blocks are possibly lost in loss
      record 113 of 125
      ==22962== at 0x402603E: malloc (vg_replace_malloc.c:207)
      ==22962== by 0x81147FD: lalloc (misc2.c:866)
      ==22962== by 0x8114708: alloc (misc2.c:765)
      ==22962== by 0x8114C16: vim_strsave (misc2.c:1177)
      ==22962== by 0x808C427: copy_tv (eval.c:19380)
      ==22962== by 0x808AE51: get_var_tv (eval.c:18452)
      ==22962== by 0x80785E7: eval7 (eval.c:5032)
      ==22962== by 0x8077EA3: eval6 (eval.c:4685)
      ==22962== by 0x8077A8F: eval5 (eval.c:4501)
      ==22962== by 0x8076FE0: eval4 (eval.c:4196)
      ==22962== by 0x8076E38: eval3 (eval.c:4108)
      ==22962== by 0x8076CC4: eval2 (eval.c:4037)
      ==22962== by 0x8076AF4: eval1 (eval.c:3962)
      ==22962== by 0x8079667: get_list_tv (eval.c:5675)
      ==22962== by 0x807837D: eval7 (eval.c:4943)
      ==22962== by 0x8077EA3: eval6 (eval.c:4685)
      ==22962== by 0x8077A8F: eval5 (eval.c:4501)
      ==22962== by 0x8076FE0: eval4 (eval.c:4196)
      ==22962== by 0x8076E38: eval3 (eval.c:4108)
      ==22962== by 0x8076CC4: eval2 (eval.c:4037)
      ==22962== by 0x8076AF4: eval1 (eval.c:3962)
      ==22962== by 0x8076A5B: eval0 (eval.c:3919)
      ==22962== by 0x807326C: ex_let (eval.c:1833)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
      ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
      ==22962== by 0x8090507: call_user_func (eval.c:21381)
      ==22962== by 0x807C6DD: call_func (eval.c:8159)
      ==22962== by 0x807C321: get_func_tv (eval.c:8005)
      ==22962== by 0x8075C03: ex_call (eval.c:3341)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
      ==22962==
      ==22962==
      ==22962== 33,288 bytes in 5,548 blocks are possibly lost in loss
      record 114 of 125
      ==22962== at 0x402603E: malloc (vg_replace_malloc.c:207)
      ==22962== by 0x81147FD: lalloc (misc2.c:866)
      ==22962== by 0x8114708: alloc (misc2.c:765)
      ==22962== by 0x8114C16: vim_strsave (misc2.c:1177)
      ==22962== by 0x808C427: copy_tv (eval.c:19380)
      ==22962== by 0x807B117: dict_copy (eval.c:6961)
      ==22962== by 0x808C662: item_copy (eval.c:19471)
      ==22962== by 0x807DB82: f_copy (eval.c:9141)
      ==22962== by 0x807C7DF: call_func (eval.c:8188)
      ==22962== by 0x807C321: get_func_tv (eval.c:8005)
      ==22962== by 0x807859A: eval7 (eval.c:5018)
      ==22962== by 0x8077EA3: eval6 (eval.c:4685)
      ==22962== by 0x8077A8F: eval5 (eval.c:4501)
      ==22962== by 0x8076FE0: eval4 (eval.c:4196)
      ==22962== by 0x8076E38: eval3 (eval.c:4108)
      ==22962== by 0x8076CC4: eval2 (eval.c:4037)
      ==22962== by 0x8076AF4: eval1 (eval.c:3962)
      ==22962== by 0x8076A5B: eval0 (eval.c:3919)
      ==22962== by 0x807326C: ex_let (eval.c:1833)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
      ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
      ==22962== by 0x8090507: call_user_func (eval.c:21381)
      ==22962== by 0x807C6DD: call_func (eval.c:8159)
      ==22962== by 0x807C321: get_func_tv (eval.c:8005)
      ==22962== by 0x8075C03: ex_call (eval.c:3341)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
      ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
      ==22962== by 0x80A2793: do_source (ex_cmds2.c:3119)
      ==22962== by 0x80A2047: cmd_source (ex_cmds2.c:2741)
      ==22962== by 0x80A1F9B: ex_source (ex_cmds2.c:2714)
      ==22962==
      ==22962==
      ==22962== 49,932 bytes in 8,322 blocks are possibly lost in loss
      record 115 of 125
      ==22962== at 0x402603E: malloc (vg_replace_malloc.c:207)
      ==22962== by 0x81147FD: lalloc (misc2.c:866)
      ==22962== by 0x8114708: alloc (misc2.c:765)
      ==22962== by 0x8114C16: vim_strsave (misc2.c:1177)
      ==22962== by 0x808C427: copy_tv (eval.c:19380)
      ==22962== by 0x807B117: dict_copy (eval.c:6961)
      ==22962== by 0x808C662: item_copy (eval.c:19471)
      ==22962== by 0x807DB82: f_copy (eval.c:9141)
      ==22962== by 0x807C7DF: call_func (eval.c:8188)
      ==22962== by 0x807C321: get_func_tv (eval.c:8005)
      ==22962== by 0x807859A: eval7 (eval.c:5018)
      ==22962== by 0x8077EA3: eval6 (eval.c:4685)
      ==22962== by 0x8077A8F: eval5 (eval.c:4501)
      ==22962== by 0x8076FE0: eval4 (eval.c:4196)
      ==22962== by 0x8076E38: eval3 (eval.c:4108)
      ==22962== by 0x8076CC4: eval2 (eval.c:4037)
      ==22962== by 0x8076AF4: eval1 (eval.c:3962)
      ==22962== by 0x8076A5B: eval0 (eval.c:3919)
      ==22962== by 0x807326C: ex_let (eval.c:1833)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
      ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
      ==22962== by 0x8090507: call_user_func (eval.c:21381)
      ==22962== by 0x807C6DD: call_func (eval.c:8159)
      ==22962== by 0x807C321: get_func_tv (eval.c:8005)
      ==22962== by 0x808AF05: handle_subscript (eval.c:18491)
      ==22962== by 0x8078640: eval7 (eval.c:5046)
      ==22962== by 0x8077EA3: eval6 (eval.c:4685)
      ==22962== by 0x8077A8F: eval5 (eval.c:4501)
      ==22962== by 0x8076FE0: eval4 (eval.c:4196)
      ==22962== by 0x8076E38: eval3 (eval.c:4108)
      ==22962==
      ==22962==
      ==22962== 58,254 bytes in 2,774 blocks are possibly lost in loss
      record 116 of 125
      ==22962== at 0x402603E: malloc (vg_replace_malloc.c:207)
      ==22962== by 0x81147FD: lalloc (misc2.c:866)
      ==22962== by 0x8114708: alloc (misc2.c:765)
      ==22962== by 0x807AEFC: dictitem_alloc (eval.c:6855)
      ==22962== by 0x807507D: set_var_lval (eval.c:2864)
      ==22962== by 0x8074374: ex_let_one (eval.c:2422)
      ==22962== by 0x807331F: ex_let_vars (eval.c:1877)
      ==22962== by 0x80732D0: ex_let (eval.c:1842)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
      ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
      ==22962== by 0x8090507: call_user_func (eval.c:21381)
      ==22962== by 0x807C6DD: call_func (eval.c:8159)
      ==22962== by 0x807C321: get_func_tv (eval.c:8005)
      ==22962== by 0x8075C03: ex_call (eval.c:3341)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
      ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
      ==22962== by 0x8090507: call_user_func (eval.c:21381)
      ==22962== by 0x807C6DD: call_func (eval.c:8159)
      ==22962== by 0x807C321: get_func_tv (eval.c:8005)
      ==22962== by 0x8075C03: ex_call (eval.c:3341)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
      ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
      ==22962== by 0x80A2793: do_source (ex_cmds2.c:3119)
      ==22962== by 0x80A2047: cmd_source (ex_cmds2.c:2741)
      ==22962== by 0x80A1F9B: ex_source (ex_cmds2.c:2714)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
      ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
      ==22962== by 0x812ACC4: nv_colon (normal.c:5227)
      ==22962== by 0x812430E: normal_cmd (normal.c:1189)
      ==22962== by 0x80E6F3D: main_loop (main.c:1180)
      ==22962==
      ==22962==
      ==22962== 77,672 bytes in 2,774 blocks are possibly lost in loss
      record 117 of 125
      ==22962== at 0x402603E: malloc (vg_replace_malloc.c:207)
      ==22962== by 0x81147FD: lalloc (misc2.c:866)
      ==22962== by 0x8114708: alloc (misc2.c:765)
      ==22962== by 0x807AEFC: dictitem_alloc (eval.c:6855)
      ==22962== by 0x807507D: set_var_lval (eval.c:2864)
      ==22962== by 0x8074374: ex_let_one (eval.c:2422)
      ==22962== by 0x807331F: ex_let_vars (eval.c:1877)
      ==22962== by 0x80732D0: ex_let (eval.c:1842)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
      ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
      ==22962== by 0x8090507: call_user_func (eval.c:21381)
      ==22962== by 0x807C6DD: call_func (eval.c:8159)
      ==22962== by 0x807C321: get_func_tv (eval.c:8005)
      ==22962== by 0x808AF05: handle_subscript (eval.c:18491)
      ==22962== by 0x8078640: eval7 (eval.c:5046)
      ==22962== by 0x8077EA3: eval6 (eval.c:4685)
      ==22962== by 0x8077A8F: eval5 (eval.c:4501)
      ==22962== by 0x8076FE0: eval4 (eval.c:4196)
      ==22962== by 0x8076E38: eval3 (eval.c:4108)
      ==22962== by 0x8076CC4: eval2 (eval.c:4037)
      ==22962== by 0x8076AF4: eval1 (eval.c:3962)
      ==22962== by 0x8076A5B: eval0 (eval.c:3919)
      ==22962== by 0x807326C: ex_let (eval.c:1833)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
      ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
      ==22962== by 0x8090507: call_user_func (eval.c:21381)
      ==22962== by 0x807C6DD: call_func (eval.c:8159)
      ==22962== by 0x807C321: get_func_tv (eval.c:8005)
      ==22962== by 0x8075C03: ex_call (eval.c:3341)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
      ==22962==
      ==22962==
      ==22962== 133,152 bytes in 5,548 blocks are possibly lost in loss
      record 118 of 125
      ==22962== at 0x402603E: malloc (vg_replace_malloc.c:207)
      ==22962== by 0x81147FD: lalloc (misc2.c:866)
      ==22962== by 0x8114708: alloc (misc2.c:765)
      ==22962== by 0x807AEFC: dictitem_alloc (eval.c:6855)
      ==22962== by 0x807B0B3: dict_copy (eval.c:6948)
      ==22962== by 0x808C662: item_copy (eval.c:19471)
      ==22962== by 0x807DB82: f_copy (eval.c:9141)
      ==22962== by 0x807C7DF: call_func (eval.c:8188)
      ==22962== by 0x807C321: get_func_tv (eval.c:8005)
      ==22962== by 0x807859A: eval7 (eval.c:5018)
      ==22962== by 0x8077EA3: eval6 (eval.c:4685)
      ==22962== by 0x8077A8F: eval5 (eval.c:4501)
      ==22962== by 0x8076FE0: eval4 (eval.c:4196)
      ==22962== by 0x8076E38: eval3 (eval.c:4108)
      ==22962== by 0x8076CC4: eval2 (eval.c:4037)
      ==22962== by 0x8076AF4: eval1 (eval.c:3962)
      ==22962== by 0x8076A5B: eval0 (eval.c:3919)
      ==22962== by 0x807326C: ex_let (eval.c:1833)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
      ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
      ==22962== by 0x8090507: call_user_func (eval.c:21381)
      ==22962== by 0x807C6DD: call_func (eval.c:8159)
      ==22962== by 0x807C321: get_func_tv (eval.c:8005)
      ==22962== by 0x8075C03: ex_call (eval.c:3341)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
      ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
      ==22962== by 0x80A2793: do_source (ex_cmds2.c:3119)
      ==22962== by 0x80A2047: cmd_source (ex_cmds2.c:2741)
      ==22962== by 0x80A1F9B: ex_source (ex_cmds2.c:2714)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
      ==22962==
      ==22962==
      ==22962== 160,892 bytes in 5,548 blocks are possibly lost in loss
      record 119 of 125
      ==22962== at 0x402603E: malloc (vg_replace_malloc.c:207)
      ==22962== by 0x81147FD: lalloc (misc2.c:866)
      ==22962== by 0x8114708: alloc (misc2.c:765)
      ==22962== by 0x807AEFC: dictitem_alloc (eval.c:6855)
      ==22962== by 0x807507D: set_var_lval (eval.c:2864)
      ==22962== by 0x8074374: ex_let_one (eval.c:2422)
      ==22962== by 0x807331F: ex_let_vars (eval.c:1877)
      ==22962== by 0x80732D0: ex_let (eval.c:1842)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
      ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
      ==22962== by 0x8090507: call_user_func (eval.c:21381)
      ==22962== by 0x807C6DD: call_func (eval.c:8159)
      ==22962== by 0x807C321: get_func_tv (eval.c:8005)
      ==22962== by 0x8075C03: ex_call (eval.c:3341)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
      ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
      ==22962== by 0x80A2793: do_source (ex_cmds2.c:3119)
      ==22962== by 0x80A2047: cmd_source (ex_cmds2.c:2741)
      ==22962== by 0x80A1F9B: ex_source (ex_cmds2.c:2714)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
      ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
      ==22962== by 0x812ACC4: nv_colon (normal.c:5227)
      ==22962== by 0x812430E: normal_cmd (normal.c:1189)
      ==22962== by 0x80E6F3D: main_loop (main.c:1180)
      ==22962== by 0x80E6A8A: main (main.c:939)
      ==22962==
      ==22962==
      ==22962== 213,598 bytes in 8,322 blocks are possibly lost in loss
      record 120 of 125
      ==22962== at 0x402603E: malloc (vg_replace_malloc.c:207)
      ==22962== by 0x81147FD: lalloc (misc2.c:866)
      ==22962== by 0x8114708: alloc (misc2.c:765)
      ==22962== by 0x807AEFC: dictitem_alloc (eval.c:6855)
      ==22962== by 0x807B0B3: dict_copy (eval.c:6948)
      ==22962== by 0x808C662: item_copy (eval.c:19471)
      ==22962== by 0x807DB82: f_copy (eval.c:9141)
      ==22962== by 0x807C7DF: call_func (eval.c:8188)
      ==22962== by 0x807C321: get_func_tv (eval.c:8005)
      ==22962== by 0x807859A: eval7 (eval.c:5018)
      ==22962== by 0x8077EA3: eval6 (eval.c:4685)
      ==22962== by 0x8077A8F: eval5 (eval.c:4501)
      ==22962== by 0x8076FE0: eval4 (eval.c:4196)
      ==22962== by 0x8076E38: eval3 (eval.c:4108)
      ==22962== by 0x8076CC4: eval2 (eval.c:4037)
      ==22962== by 0x8076AF4: eval1 (eval.c:3962)
      ==22962== by 0x8076A5B: eval0 (eval.c:3919)
      ==22962== by 0x807326C: ex_let (eval.c:1833)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
      ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
      ==22962== by 0x8090507: call_user_func (eval.c:21381)
      ==22962== by 0x807C6DD: call_func (eval.c:8159)
      ==22962== by 0x807C321: get_func_tv (eval.c:8005)
      ==22962== by 0x808AF05: handle_subscript (eval.c:18491)
      ==22962== by 0x8078640: eval7 (eval.c:5046)
      ==22962== by 0x8077EA3: eval6 (eval.c:4685)
      ==22962== by 0x8077A8F: eval5 (eval.c:4501)
      ==22962== by 0x8076FE0: eval4 (eval.c:4196)
      ==22962== by 0x8076E38: eval3 (eval.c:4108)
      ==22962== by 0x8076CC4: eval2 (eval.c:4037)
      ==22962==
      ==22962==
      ==22962== 288,496 bytes in 5,548 blocks are possibly lost in loss
      record 121 of 125
      ==22962== at 0x402603E: malloc (vg_replace_malloc.c:207)
      ==22962== by 0x81147FD: lalloc (misc2.c:866)
      ==22962== by 0x8114723: alloc_clear (misc2.c:777)
      ==22962== by 0x80797D0: list_alloc (eval.c:5729)
      ==22962== by 0x807961D: get_list_tv (eval.c:5667)
      ==22962== by 0x807837D: eval7 (eval.c:4943)
      ==22962== by 0x8077EA3: eval6 (eval.c:4685)
      ==22962== by 0x8077A8F: eval5 (eval.c:4501)
      ==22962== by 0x8076FE0: eval4 (eval.c:4196)
      ==22962== by 0x8076E38: eval3 (eval.c:4108)
      ==22962== by 0x8076CC4: eval2 (eval.c:4037)
      ==22962== by 0x8076AF4: eval1 (eval.c:3962)
      ==22962== by 0x8076A5B: eval0 (eval.c:3919)
      ==22962== by 0x807326C: ex_let (eval.c:1833)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
      ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
      ==22962== by 0x8090507: call_user_func (eval.c:21381)
      ==22962== by 0x807C6DD: call_func (eval.c:8159)
      ==22962== by 0x807C321: get_func_tv (eval.c:8005)
      ==22962== by 0x8075C03: ex_call (eval.c:3341)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
      ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
      ==22962== by 0x8090507: call_user_func (eval.c:21381)
      ==22962== by 0x807C6DD: call_func (eval.c:8159)
      ==22962== by 0x807C321: get_func_tv (eval.c:8005)
      ==22962== by 0x8075C03: ex_call (eval.c:3341)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
      ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
      ==22962== by 0x80A2793: do_source (ex_cmds2.c:3119)
      ==22962== by 0x80A2047: cmd_source (ex_cmds2.c:2741)
      ==22962==
      ==22962==
      ==22962== 399,456 bytes in 16,644 blocks are possibly lost in loss
      record 122 of 125
      ==22962== at 0x402603E: malloc (vg_replace_malloc.c:207)
      ==22962== by 0x81147FD: lalloc (misc2.c:866)
      ==22962== by 0x8114708: alloc (misc2.c:765)
      ==22962== by 0x807994D: listitem_alloc (eval.c:5810)
      ==22962== by 0x807967A: get_list_tv (eval.c:5679)
      ==22962== by 0x807837D: eval7 (eval.c:4943)
      ==22962== by 0x8077EA3: eval6 (eval.c:4685)
      ==22962== by 0x8077A8F: eval5 (eval.c:4501)
      ==22962== by 0x8076FE0: eval4 (eval.c:4196)
      ==22962== by 0x8076E38: eval3 (eval.c:4108)
      ==22962== by 0x8076CC4: eval2 (eval.c:4037)
      ==22962== by 0x8076AF4: eval1 (eval.c:3962)
      ==22962== by 0x8076A5B: eval0 (eval.c:3919)
      ==22962== by 0x807326C: ex_let (eval.c:1833)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
      ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
      ==22962== by 0x8090507: call_user_func (eval.c:21381)
      ==22962== by 0x807C6DD: call_func (eval.c:8159)
      ==22962== by 0x807C321: get_func_tv (eval.c:8005)
      ==22962== by 0x8075C03: ex_call (eval.c:3341)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
      ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
      ==22962== by 0x8090507: call_user_func (eval.c:21381)
      ==22962== by 0x807C6DD: call_func (eval.c:8159)
      ==22962== by 0x807C321: get_func_tv (eval.c:8005)
      ==22962== by 0x8075C03: ex_call (eval.c:3341)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
      ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
      ==22962== by 0x80A2793: do_source (ex_cmds2.c:3119)
      ==22962== by 0x80A2047: cmd_source (ex_cmds2.c:2741)
      ==22962==
      ==22962==
      ==22962== 499,320 bytes in 2,774 blocks are possibly lost in loss
      record 123 of 125
      ==22962== at 0x402603E: malloc (vg_replace_malloc.c:207)
      ==22962== by 0x81147FD: lalloc (misc2.c:866)
      ==22962== by 0x8114708: alloc (misc2.c:765)
      ==22962== by 0x807AD1E: dict_alloc (eval.c:6770)
      ==22962== by 0x807B6A8: get_dict_tv (eval.c:7216)
      ==22962== by 0x807839E: eval7 (eval.c:4949)
      ==22962== by 0x8077EA3: eval6 (eval.c:4685)
      ==22962== by 0x8077A8F: eval5 (eval.c:4501)
      ==22962== by 0x8076FE0: eval4 (eval.c:4196)
      ==22962== by 0x8076E38: eval3 (eval.c:4108)
      ==22962== by 0x8076CC4: eval2 (eval.c:4037)
      ==22962== by 0x8076AF4: eval1 (eval.c:3962)
      ==22962== by 0x8076A5B: eval0 (eval.c:3919)
      ==22962== by 0x807326C: ex_let (eval.c:1833)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
      ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
      ==22962== by 0x8090507: call_user_func (eval.c:21381)
      ==22962== by 0x807C6DD: call_func (eval.c:8159)
      ==22962== by 0x807C321: get_func_tv (eval.c:8005)
      ==22962== by 0x808AF05: handle_subscript (eval.c:18491)
      ==22962== by 0x8078640: eval7 (eval.c:5046)
      ==22962== by 0x8077EA3: eval6 (eval.c:4685)
      ==22962== by 0x8077A8F: eval5 (eval.c:4501)
      ==22962== by 0x8076FE0: eval4 (eval.c:4196)
      ==22962== by 0x8076E38: eval3 (eval.c:4108)
      ==22962== by 0x8076CC4: eval2 (eval.c:4037)
      ==22962== by 0x8076AF4: eval1 (eval.c:3962)
      ==22962== by 0x8076A5B: eval0 (eval.c:3919)
      ==22962== by 0x807326C: ex_let (eval.c:1833)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
      ==22962==
      ==22962==
      ==22962== 499,320 bytes in 2,774 blocks are possibly lost in loss
      record 124 of 125
      ==22962== at 0x402603E: malloc (vg_replace_malloc.c:207)
      ==22962== by 0x81147FD: lalloc (misc2.c:866)
      ==22962== by 0x8114708: alloc (misc2.c:765)
      ==22962== by 0x807AD1E: dict_alloc (eval.c:6770)
      ==22962== by 0x807B040: dict_copy (eval.c:6933)
      ==22962== by 0x808C662: item_copy (eval.c:19471)
      ==22962== by 0x807DB82: f_copy (eval.c:9141)
      ==22962== by 0x807C7DF: call_func (eval.c:8188)
      ==22962== by 0x807C321: get_func_tv (eval.c:8005)
      ==22962== by 0x807859A: eval7 (eval.c:5018)
      ==22962== by 0x8077EA3: eval6 (eval.c:4685)
      ==22962== by 0x8077A8F: eval5 (eval.c:4501)
      ==22962== by 0x8076FE0: eval4 (eval.c:4196)
      ==22962== by 0x8076E38: eval3 (eval.c:4108)
      ==22962== by 0x8076CC4: eval2 (eval.c:4037)
      ==22962== by 0x8076AF4: eval1 (eval.c:3962)
      ==22962== by 0x8076A5B: eval0 (eval.c:3919)
      ==22962== by 0x807326C: ex_let (eval.c:1833)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
      ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
      ==22962== by 0x8090507: call_user_func (eval.c:21381)
      ==22962== by 0x807C6DD: call_func (eval.c:8159)
      ==22962== by 0x807C321: get_func_tv (eval.c:8005)
      ==22962== by 0x808AF05: handle_subscript (eval.c:18491)
      ==22962== by 0x8078640: eval7 (eval.c:5046)
      ==22962== by 0x8077EA3: eval6 (eval.c:4685)
      ==22962== by 0x8077A8F: eval5 (eval.c:4501)
      ==22962== by 0x8076FE0: eval4 (eval.c:4196)
      ==22962== by 0x8076E38: eval3 (eval.c:4108)
      ==22962== by 0x8076CC4: eval2 (eval.c:4037)
      ==22962==
      ==22962==
      ==22962== 499,320 bytes in 2,774 blocks are possibly lost in loss
      record 125 of 125
      ==22962== at 0x402603E: malloc (vg_replace_malloc.c:207)
      ==22962== by 0x81147FD: lalloc (misc2.c:866)
      ==22962== by 0x8114708: alloc (misc2.c:765)
      ==22962== by 0x807AD1E: dict_alloc (eval.c:6770)
      ==22962== by 0x807B040: dict_copy (eval.c:6933)
      ==22962== by 0x808C662: item_copy (eval.c:19471)
      ==22962== by 0x807DB82: f_copy (eval.c:9141)
      ==22962== by 0x807C7DF: call_func (eval.c:8188)
      ==22962== by 0x807C321: get_func_tv (eval.c:8005)
      ==22962== by 0x807859A: eval7 (eval.c:5018)
      ==22962== by 0x8077EA3: eval6 (eval.c:4685)
      ==22962== by 0x8077A8F: eval5 (eval.c:4501)
      ==22962== by 0x8076FE0: eval4 (eval.c:4196)
      ==22962== by 0x8076E38: eval3 (eval.c:4108)
      ==22962== by 0x8076CC4: eval2 (eval.c:4037)
      ==22962== by 0x8076AF4: eval1 (eval.c:3962)
      ==22962== by 0x8076A5B: eval0 (eval.c:3919)
      ==22962== by 0x807326C: ex_let (eval.c:1833)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
      ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
      ==22962== by 0x8090507: call_user_func (eval.c:21381)
      ==22962== by 0x807C6DD: call_func (eval.c:8159)
      ==22962== by 0x807C321: get_func_tv (eval.c:8005)
      ==22962== by 0x8075C03: ex_call (eval.c:3341)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
      ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
      ==22962== by 0x80A2793: do_source (ex_cmds2.c:3119)
      ==22962== by 0x80A2047: cmd_source (ex_cmds2.c:2741)
      ==22962== by 0x80A1F9B: ex_source (ex_cmds2.c:2714)
      ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)

      -- Dominique

      --~--~---------~--~----~------------~-------~--~----~
      You received this message from the "vim_dev" maillist.
      For more information, visit http://www.vim.org/maillist.php
      -~----------~----~----~----~------~----~------~--~---
    • Bram Moolenaar
      ... I m very glad you managed to pinpoint the problem and fix it. I ll check the details and include the patch. Thanks! -- The Law of VIM: For each member b of
      Message 2 of 12 , May 5, 2009
        Nico Weber wrote:

        > Valgrind memory checker finds several errors in vim-7.2 (patches
        > 1-148) with the reproduction steps described at http://groups.google.com/group/vim_mac/browse_thread/thread/4e0149ff4f84e3d3
        > :
        >
        > ==33469== Conditional jump or move depends on uninitialised value(s)
        > ==33469== at 0x437EA: can_free_funccal (eval.c:21449)
        > ==33469== by 0x2D213: garbage_collect (eval.c:6591)
        > ==33469== by 0x8D92E: before_blocking (getchar.c:1473)
        > ==33469== by 0x10764F: mch_inchar (os_unix.c:385)
        > ==33469== by 0x176A06: ui_inchar (ui.c:193)
        > ==33469== by 0x8FFD1: inchar (getchar.c:2959)
        > ==33469== by 0x8FB64: vgetorpeek (getchar.c:2735)
        > ==33469== by 0x8DAA3: vgetc (getchar.c:1552)
        > ==33469== by 0x8E05D: safe_vgetc (getchar.c:1757)
        > ==33469== by 0xDC89D: normal_cmd (normal.c:653)
        > ==33469== by 0x9F674: main_loop (main.c:1255)
        > ==33469== by 0x9F167: main (main.c:1002)
        > ==33469==
        > ==33469== Conditional jump or move depends on uninitialised value(s)
        > ==33469== at 0x437F8: can_free_funccal (eval.c:21449)
        > ==33469== by 0x2D213: garbage_collect (eval.c:6591)
        > ==33469== by 0x8D92E: before_blocking (getchar.c:1473)
        > ==33469== by 0x10764F: mch_inchar (os_unix.c:385)
        > ==33469== by 0x176A06: ui_inchar (ui.c:193)
        > ==33469== by 0x8FFD1: inchar (getchar.c:2959)
        > ==33469== by 0x8FB64: vgetorpeek (getchar.c:2735)
        > ==33469== by 0x8DAA3: vgetc (getchar.c:1552)
        > ==33469== by 0x8E05D: safe_vgetc (getchar.c:1757)
        > ==33469== by 0xDC89D: normal_cmd (normal.c:653)
        > ==33469== by 0x9F674: main_loop (main.c:1255)
        > ==33469== by 0x9F167: main (main.c:1002)
        > ==33469==
        > ==33469== Invalid read of size 4
        > ==33469== at 0x2D451: dict_unref (eval.c:6709)
        > ==33469== by 0x3E4E7: clear_tv (eval.c:18558)
        > ==33469== by 0x3F09B: vars_clear_ext (eval.c:18994)
        > ==33469== by 0x4382B: free_funccal (eval.c:21466)
        > ==33469== by 0x2D240: garbage_collect (eval.c:6595)
        > ==33469== by 0x8D92E: before_blocking (getchar.c:1473)
        > ==33469== by 0x10764F: mch_inchar (os_unix.c:385)
        > ==33469== by 0x176A06: ui_inchar (ui.c:193)
        > ==33469== by 0x8FFD1: inchar (getchar.c:2959)
        > ==33469== by 0x8FB64: vgetorpeek (getchar.c:2735)
        > ==33469== by 0x8DAA3: vgetc (getchar.c:1552)
        > ==33469== by 0x8E05D: safe_vgetc (getchar.c:1757)
        > ==33469== Address 0x7c290f0 is 0 bytes inside a block of size 176
        > free'd
        > ==33469== at 0x25661B: free (vg_replace_malloc.c:322)
        > ==33469== by 0xCDBDC: vim_free (misc2.c:1638)
        > ==33469== by 0x2D59B: dict_free (eval.c:6753)
        > ==33469== by 0x2D176: garbage_collect (eval.c:6559)
        > ==33469== by 0x8D92E: before_blocking (getchar.c:1473)
        > ==33469== by 0x10764F: mch_inchar (os_unix.c:385)
        > ==33469== by 0x176A06: ui_inchar (ui.c:193)
        > ==33469== by 0x8FFD1: inchar (getchar.c:2959)
        > ==33469== by 0x8FB64: vgetorpeek (getchar.c:2735)
        > ==33469== by 0x8DAA3: vgetc (getchar.c:1552)
        > ==33469== by 0x8E05D: safe_vgetc (getchar.c:1757)
        > ==33469== by 0xDC89D: normal_cmd (normal.c:653)
        > ==33469==
        > ==33469== Invalid write of size 4
        > ==33469== at 0x2D459: dict_unref (eval.c:6709)
        > ==33469== by 0x3E4E7: clear_tv (eval.c:18558)
        > ==33469== by 0x3F09B: vars_clear_ext (eval.c:18994)
        > ==33469== by 0x4382B: free_funccal (eval.c:21466)
        > ==33469== by 0x2D240: garbage_collect (eval.c:6595)
        > ==33469== by 0x8D92E: before_blocking (getchar.c:1473)
        > ==33469== by 0x10764F: mch_inchar (os_unix.c:385)
        > ==33469== by 0x176A06: ui_inchar (ui.c:193)
        > ==33469== by 0x8FFD1: inchar (getchar.c:2959)
        > ==33469== by 0x8FB64: vgetorpeek (getchar.c:2735)
        > ==33469== by 0x8DAA3: vgetc (getchar.c:1552)
        > ==33469== by 0x8E05D: safe_vgetc (getchar.c:1757)
        > ==33469== Address 0x7c290f0 is 0 bytes inside a block of size 176
        > free'd
        > ==33469== at 0x25661B: free (vg_replace_malloc.c:322)
        > ==33469== by 0xCDBDC: vim_free (misc2.c:1638)
        > ==33469== by 0x2D59B: dict_free (eval.c:6753)
        > ==33469== by 0x2D176: garbage_collect (eval.c:6559)
        > ==33469== by 0x8D92E: before_blocking (getchar.c:1473)
        > ==33469== by 0x10764F: mch_inchar (os_unix.c:385)
        > ==33469== by 0x176A06: ui_inchar (ui.c:193)
        > ==33469== by 0x8FFD1: inchar (getchar.c:2959)
        > ==33469== by 0x8FB64: vgetorpeek (getchar.c:2735)
        > ==33469== by 0x8DAA3: vgetc (getchar.c:1552)
        > ==33469== by 0x8E05D: safe_vgetc (getchar.c:1757)
        > ==33469== by 0xDC89D: normal_cmd (normal.c:653)
        > ==33469==
        > ==33469== Invalid read of size 4
        > ==33469== at 0x2D45E: dict_unref (eval.c:6709)
        > ==33469== by 0x3E4E7: clear_tv (eval.c:18558)
        > ==33469== by 0x3F09B: vars_clear_ext (eval.c:18994)
        > ==33469== by 0x4382B: free_funccal (eval.c:21466)
        > ==33469== by 0x2D240: garbage_collect (eval.c:6595)
        > ==33469== by 0x8D92E: before_blocking (getchar.c:1473)
        > ==33469== by 0x10764F: mch_inchar (os_unix.c:385)
        > ==33469== by 0x176A06: ui_inchar (ui.c:193)
        > ==33469== by 0x8FFD1: inchar (getchar.c:2959)
        > ==33469== by 0x8FB64: vgetorpeek (getchar.c:2735)
        > ==33469== by 0x8DAA3: vgetc (getchar.c:1552)
        > ==33469== by 0x8E05D: safe_vgetc (getchar.c:1757)
        > ==33469== Address 0x7c290f0 is 0 bytes inside a block of size 176
        > free'd
        > ==33469== at 0x25661B: free (vg_replace_malloc.c:322)
        > ==33469== by 0xCDBDC: vim_free (misc2.c:1638)
        > ==33469== by 0x2D59B: dict_free (eval.c:6753)
        > ==33469== by 0x2D176: garbage_collect (eval.c:6559)
        > ==33469== by 0x8D92E: before_blocking (getchar.c:1473)
        > ==33469== by 0x10764F: mch_inchar (os_unix.c:385)
        > ==33469== by 0x176A06: ui_inchar (ui.c:193)
        > ==33469== by 0x8FFD1: inchar (getchar.c:2959)
        > ==33469== by 0x8FB64: vgetorpeek (getchar.c:2735)
        > ==33469== by 0x8DAA3: vgetc (getchar.c:1552)
        > ==33469== by 0x8E05D: safe_vgetc (getchar.c:1757)
        > ==33469== by 0xDC89D: normal_cmd (normal.c:653)
        > ==33469==
        > ==33469== Invalid read of size 4
        > ==33469== at 0x2BFD3: list_unref (eval.c:5761)
        > ==33469== by 0x3E4CD: clear_tv (eval.c:18554)
        > ==33469== by 0x3F09B: vars_clear_ext (eval.c:18994)
        > ==33469== by 0x3F02F: vars_clear (eval.c:18966)
        > ==33469== by 0x4383B: free_funccal (eval.c:21469)
        > ==33469== by 0x2D240: garbage_collect (eval.c:6595)
        > ==33469== by 0x8D92E: before_blocking (getchar.c:1473)
        > ==33469== by 0x10764F: mch_inchar (os_unix.c:385)
        > ==33469== by 0x176A06: ui_inchar (ui.c:193)
        > ==33469== by 0x8FFD1: inchar (getchar.c:2959)
        > ==33469== by 0x8FB64: vgetorpeek (getchar.c:2735)
        > ==33469== by 0x8DAA3: vgetc (getchar.c:1552)
        > ==33469== Address 0x7c34a58 is 8 bytes inside a block of size 48 free'd
        > ==33469== at 0x25661B: free (vg_replace_malloc.c:322)
        > ==33469== by 0xCDBDC: vim_free (misc2.c:1638)
        > ==33469== by 0x2C0AE: list_free (eval.c:5793)
        > ==33469== by 0x2D1D1: garbage_collect (eval.c:6579)
        > ==33469== by 0x8D92E: before_blocking (getchar.c:1473)
        > ==33469== by 0x10764F: mch_inchar (os_unix.c:385)
        > ==33469== by 0x176A06: ui_inchar (ui.c:193)
        > ==33469== by 0x8FFD1: inchar (getchar.c:2959)
        > ==33469== by 0x8FB64: vgetorpeek (getchar.c:2735)
        > ==33469== by 0x8DAA3: vgetc (getchar.c:1552)
        > ==33469== by 0x8E05D: safe_vgetc (getchar.c:1757)
        > ==33469== by 0xDC89D: normal_cmd (normal.c:653)
        > ==33469==
        > ==33469== Invalid write of size 4
        > ==33469== at 0x2BFDC: list_unref (eval.c:5761)
        > ==33469== by 0x3E4CD: clear_tv (eval.c:18554)
        > ==33469== by 0x3F09B: vars_clear_ext (eval.c:18994)
        > ==33469== by 0x3F02F: vars_clear (eval.c:18966)
        > ==33469== by 0x4383B: free_funccal (eval.c:21469)
        > ==33469== by 0x2D240: garbage_collect (eval.c:6595)
        > ==33469== by 0x8D92E: before_blocking (getchar.c:1473)
        > ==33469== by 0x10764F: mch_inchar (os_unix.c:385)
        > ==33469== by 0x176A06: ui_inchar (ui.c:193)
        > ==33469== by 0x8FFD1: inchar (getchar.c:2959)
        > ==33469== by 0x8FB64: vgetorpeek (getchar.c:2735)
        > ==33469== by 0x8DAA3: vgetc (getchar.c:1552)
        > ==33469== Address 0x7c34a58 is 8 bytes inside a block of size 48 free'd
        > ==33469== at 0x25661B: free (vg_replace_malloc.c:322)
        > ==33469== by 0xCDBDC: vim_free (misc2.c:1638)
        > ==33469== by 0x2C0AE: list_free (eval.c:5793)
        > ==33469== by 0x2D1D1: garbage_collect (eval.c:6579)
        > ==33469== by 0x8D92E: before_blocking (getchar.c:1473)
        > ==33469== by 0x10764F: mch_inchar (os_unix.c:385)
        > ==33469== by 0x176A06: ui_inchar (ui.c:193)
        > ==33469== by 0x8FFD1: inchar (getchar.c:2959)
        > ==33469== by 0x8FB64: vgetorpeek (getchar.c:2735)
        > ==33469== by 0x8DAA3: vgetc (getchar.c:1552)
        > ==33469== by 0x8E05D: safe_vgetc (getchar.c:1757)
        > ==33469== by 0xDC89D: normal_cmd (normal.c:653)
        > ==33469==
        > ==33469== Invalid read of size 4
        > ==33469== at 0x2BFE2: list_unref (eval.c:5761)
        > ==33469== by 0x3E4CD: clear_tv (eval.c:18554)
        > ==33469== by 0x3F09B: vars_clear_ext (eval.c:18994)
        > ==33469== by 0x3F02F: vars_clear (eval.c:18966)
        > ==33469== by 0x4383B: free_funccal (eval.c:21469)
        > ==33469== by 0x2D240: garbage_collect (eval.c:6595)
        > ==33469== by 0x8D92E: before_blocking (getchar.c:1473)
        > ==33469== by 0x10764F: mch_inchar (os_unix.c:385)
        > ==33469== by 0x176A06: ui_inchar (ui.c:193)
        > ==33469== by 0x8FFD1: inchar (getchar.c:2959)
        > ==33469== by 0x8FB64: vgetorpeek (getchar.c:2735)
        > ==33469== by 0x8DAA3: vgetc (getchar.c:1552)
        > ==33469== Address 0x7c34a58 is 8 bytes inside a block of size 48 free'd
        > ==33469== at 0x25661B: free (vg_replace_malloc.c:322)
        > ==33469== by 0xCDBDC: vim_free (misc2.c:1638)
        > ==33469== by 0x2C0AE: list_free (eval.c:5793)
        > ==33469== by 0x2D1D1: garbage_collect (eval.c:6579)
        > ==33469== by 0x8D92E: before_blocking (getchar.c:1473)
        > ==33469== by 0x10764F: mch_inchar (os_unix.c:385)
        > ==33469== by 0x176A06: ui_inchar (ui.c:193)
        > ==33469== by 0x8FFD1: inchar (getchar.c:2959)
        > ==33469== by 0x8FB64: vgetorpeek (getchar.c:2735)
        > ==33469== by 0x8DAA3: vgetc (getchar.c:1552)
        > ==33469== by 0x8E05D: safe_vgetc (getchar.c:1757)
        > ==33469== by 0xDC89D: normal_cmd (normal.c:653)
        > ==33469==
        > ==33469== Invalid read of size 4
        > ==33469== at 0x2D451: dict_unref (eval.c:6709)
        > ==33469== by 0x3E4E7: clear_tv (eval.c:18558)
        > ==33469== by 0x3F09B: vars_clear_ext (eval.c:18994)
        > ==33469== by 0x3F02F: vars_clear (eval.c:18966)
        > ==33469== by 0x4383B: free_funccal (eval.c:21469)
        > ==33469== by 0x2D240: garbage_collect (eval.c:6595)
        > ==33469== by 0x8D92E: before_blocking (getchar.c:1473)
        > ==33469== by 0x10764F: mch_inchar (os_unix.c:385)
        > ==33469== by 0x176A06: ui_inchar (ui.c:193)
        > ==33469== by 0x8FFD1: inchar (getchar.c:2959)
        > ==33469== by 0x8FB64: vgetorpeek (getchar.c:2735)
        > ==33469== by 0x8DAA3: vgetc (getchar.c:1552)
        > ==33469== Address 0x7c33af0 is 0 bytes inside a block of size 176
        > free'd
        > ==33469== at 0x25661B: free (vg_replace_malloc.c:322)
        > ==33469== by 0xCDBDC: vim_free (misc2.c:1638)
        > ==33469== by 0x2D59B: dict_free (eval.c:6753)
        > ==33469== by 0x2D176: garbage_collect (eval.c:6559)
        > ==33469== by 0x8D92E: before_blocking (getchar.c:1473)
        > ==33469== by 0x10764F: mch_inchar (os_unix.c:385)
        > ==33469== by 0x176A06: ui_inchar (ui.c:193)
        > ==33469== by 0x8FFD1: inchar (getchar.c:2959)
        > ==33469== by 0x8FB64: vgetorpeek (getchar.c:2735)
        > ==33469== by 0x8DAA3: vgetc (getchar.c:1552)
        > ==33469== by 0x8E05D: safe_vgetc (getchar.c:1757)
        > ==33469== by 0xDC89D: normal_cmd (normal.c:653)
        > ==33469==
        > ==33469== Invalid write of size 4
        > ==33469== at 0x2D459: dict_unref (eval.c:6709)
        > ==33469== by 0x3E4E7: clear_tv (eval.c:18558)
        > ==33469== by 0x3F09B: vars_clear_ext (eval.c:18994)
        > ==33469== by 0x3F02F: vars_clear (eval.c:18966)
        > ==33469== by 0x4383B: free_funccal (eval.c:21469)
        > ==33469== by 0x2D240: garbage_collect (eval.c:6595)
        > ==33469== by 0x8D92E: before_blocking (getchar.c:1473)
        > ==33469== by 0x10764F: mch_inchar (os_unix.c:385)
        > ==33469== by 0x176A06: ui_inchar (ui.c:193)
        > ==33469== by 0x8FFD1: inchar (getchar.c:2959)
        > ==33469== by 0x8FB64: vgetorpeek (getchar.c:2735)
        > ==33469== by 0x8DAA3: vgetc (getchar.c:1552)
        > ==33469== Address 0x7c33af0 is 0 bytes inside a block of size 176
        > free'd
        > ==33469== at 0x25661B: free (vg_replace_malloc.c:322)
        > ==33469== by 0xCDBDC: vim_free (misc2.c:1638)
        > ==33469== by 0x2D59B: dict_free (eval.c:6753)
        > ==33469== by 0x2D176: garbage_collect (eval.c:6559)
        > ==33469== by 0x8D92E: before_blocking (getchar.c:1473)
        > ==33469== by 0x10764F: mch_inchar (os_unix.c:385)
        > ==33469== by 0x176A06: ui_inchar (ui.c:193)
        > ==33469== by 0x8FFD1: inchar (getchar.c:2959)
        > ==33469== by 0x8FB64: vgetorpeek (getchar.c:2735)
        > ==33469== by 0x8DAA3: vgetc (getchar.c:1552)
        > ==33469== by 0x8E05D: safe_vgetc (getchar.c:1757)
        > ==33469== by 0xDC89D: normal_cmd (normal.c:653)
        > ==33469==
        > ==33469== Invalid read of size 4
        > ==33469== at 0x2D45E: dict_unref (eval.c:6709)
        > ==33469== by 0x3E4E7: clear_tv (eval.c:18558)
        > ==33469== by 0x3F09B: vars_clear_ext (eval.c:18994)
        > ==33469== by 0x3F02F: vars_clear (eval.c:18966)
        > ==33469== by 0x4383B: free_funccal (eval.c:21469)
        > ==33469== by 0x2D240: garbage_collect (eval.c:6595)
        > ==33469== by 0x8D92E: before_blocking (getchar.c:1473)
        > ==33469== by 0x10764F: mch_inchar (os_unix.c:385)
        > ==33469== by 0x176A06: ui_inchar (ui.c:193)
        > ==33469== by 0x8FFD1: inchar (getchar.c:2959)
        > ==33469== by 0x8FB64: vgetorpeek (getchar.c:2735)
        > ==33469== by 0x8DAA3: vgetc (getchar.c:1552)
        > ==33469== Address 0x7c33af0 is 0 bytes inside a block of size 176
        > free'd
        > ==33469== at 0x25661B: free (vg_replace_malloc.c:322)
        > ==33469== by 0xCDBDC: vim_free (misc2.c:1638)
        > ==33469== by 0x2D59B: dict_free (eval.c:6753)
        > ==33469== by 0x2D176: garbage_collect (eval.c:6559)
        > ==33469== by 0x8D92E: before_blocking (getchar.c:1473)
        > ==33469== by 0x10764F: mch_inchar (os_unix.c:385)
        > ==33469== by 0x176A06: ui_inchar (ui.c:193)
        > ==33469== by 0x8FFD1: inchar (getchar.c:2959)
        > ==33469== by 0x8FB64: vgetorpeek (getchar.c:2735)
        > ==33469== by 0x8DAA3: vgetc (getchar.c:1552)
        > ==33469== by 0x8E05D: safe_vgetc (getchar.c:1757)
        > ==33469== by 0xDC89D: normal_cmd (normal.c:653)
        >
        > On OS X, this leads to a crash. The problem was found by Meikel
        > Brandmeyer.
        >
        > The attached patch fixes this.
        >
        >
        > There were two problems:
        >
        > 1. Without
        >
        > dict->dv_copyID = 0;
        >
        > the l_vars and l_avars dicts in funccall_T have no initialized
        > dv_copyID at the end of call_user_func, and hence valgrind complains
        > when garbage_collect walks the previous_funccal list
        >
        > 2. Double free. garbage_collect() frees dictionaries and lists,
        > including the ones belonging to functions in the previous_funccal
        > list. When the previou_funccal list is freed, these dictionaries and
        > lists are freed a second time.

        I'm very glad you managed to pinpoint the problem and fix it.
        I'll check the details and include the patch.
        Thanks!

        --
        The Law of VIM:
        For each member b of the possible behaviour space B of program P, there exists
        a finite time t before which at least one user u in the total user space U of
        program P will request b becomes a member of the allowed behaviour space B'
        (B' <= B).
        In other words: Sooner or later everyone wants everything as an option.
        -- Vince Negri

        /// Bram Moolenaar -- Bram@... -- 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
        -~----------~----~----~----~------~----~------~--~---
      • Nico Weber
        Hi Bram ... as Dominique pointed out, while this patch fixes a double free(), it introduces a memory leak. The leak is smaller in the improved patch, but it s
        Message 3 of 12 , May 5, 2009
          Hi Bram

          On 05.05.2009, at 03:41, Bram Moolenaar wrote:

          > Nico Weber wrote:
          >
          >> Valgrind memory checker finds several errors in vim-7.2 (patches
          >> 1-148) with the reproduction steps described at http://groups.google.com/group/vim_mac/browse_thread/thread/4e0149ff4f84e3d3
          >> :
          >>
          >> ==33469== Invalid read of size 4
          >> ==33469== at 0x2D451: dict_unref (eval.c:6709)
          >> ==33469== by 0x3E4E7: clear_tv (eval.c:18558)
          >> ==33469== by 0x3F09B: vars_clear_ext (eval.c:18994)
          >> ==33469== by 0x4382B: free_funccal (eval.c:21466)
          >> ==33469== by 0x2D240: garbage_collect (eval.c:6595)
          >> ==33469== by 0x8D92E: before_blocking (getchar.c:1473)
          >> ==33469== by 0x10764F: mch_inchar (os_unix.c:385)
          >> ==33469== by 0x176A06: ui_inchar (ui.c:193)
          >> ==33469== by 0x8FFD1: inchar (getchar.c:2959)
          >> ==33469== by 0x8FB64: vgetorpeek (getchar.c:2735)
          >> ==33469== by 0x8DAA3: vgetc (getchar.c:1552)
          >> ==33469== by 0x8E05D: safe_vgetc (getchar.c:1757)
          >> ==33469== Address 0x7c290f0 is 0 bytes inside a block of size 176
          >> free'd
          >> ==33469== at 0x25661B: free (vg_replace_malloc.c:322)
          >> ==33469== by 0xCDBDC: vim_free (misc2.c:1638)
          >> ==33469== by 0x2D59B: dict_free (eval.c:6753)
          >> ==33469== by 0x2D176: garbage_collect (eval.c:6559)
          >> ==33469== by 0x8D92E: before_blocking (getchar.c:1473)
          >> ==33469== by 0x10764F: mch_inchar (os_unix.c:385)
          >> ==33469== by 0x176A06: ui_inchar (ui.c:193)
          >> ==33469== by 0x8FFD1: inchar (getchar.c:2959)
          >> ==33469== by 0x8FB64: vgetorpeek (getchar.c:2735)
          >> ==33469== by 0x8DAA3: vgetc (getchar.c:1552)
          >> ==33469== by 0x8E05D: safe_vgetc (getchar.c:1757)
          >> ==33469== by 0xDC89D: normal_cmd (normal.c:653)
          >> ==33469==
          >> ==33469== Invalid write of size 4
          >> ==33469== at 0x2D459: dict_unref (eval.c:6709)
          >> ==33469== by 0x3E4E7: clear_tv (eval.c:18558)
          >> ==33469== by 0x3F09B: vars_clear_ext (eval.c:18994)
          >> ==33469== by 0x4382B: free_funccal (eval.c:21466)
          >> ==33469== by 0x2D240: garbage_collect (eval.c:6595)
          >> ==33469== by 0x8D92E: before_blocking (getchar.c:1473)
          >> ==33469== by 0x10764F: mch_inchar (os_unix.c:385)
          >> ==33469== by 0x176A06: ui_inchar (ui.c:193)
          >> ==33469== by 0x8FFD1: inchar (getchar.c:2959)
          >> ==33469== by 0x8FB64: vgetorpeek (getchar.c:2735)
          >> ==33469== by 0x8DAA3: vgetc (getchar.c:1552)
          >> ==33469== by 0x8E05D: safe_vgetc (getchar.c:1757)
          >> ==33469== Address 0x7c290f0 is 0 bytes inside a block of size 176
          >> free'd
          >> ==33469== at 0x25661B: free (vg_replace_malloc.c:322)
          >> ==33469== by 0xCDBDC: vim_free (misc2.c:1638)
          >> ==33469== by 0x2D59B: dict_free (eval.c:6753)
          >> ==33469== by 0x2D176: garbage_collect (eval.c:6559)
          >> ==33469== by 0x8D92E: before_blocking (getchar.c:1473)
          >> ==33469== by 0x10764F: mch_inchar (os_unix.c:385)
          >> ==33469== by 0x176A06: ui_inchar (ui.c:193)
          >> ==33469== by 0x8FFD1: inchar (getchar.c:2959)
          >> ==33469== by 0x8FB64: vgetorpeek (getchar.c:2735)
          >> ==33469== by 0x8DAA3: vgetc (getchar.c:1552)
          >> ==33469== by 0x8E05D: safe_vgetc (getchar.c:1757)
          >> ==33469== by 0xDC89D: normal_cmd (normal.c:653)
          >>
          > I'm very glad you managed to pinpoint the problem and fix it.
          > I'll check the details and include the patch.
          > Thanks!

          as Dominique pointed out, while this patch fixes a double free(), it
          introduces a memory leak. The leak is smaller in the improved patch,
          but it's still there. Now, a leak is arguably better than a crash, but
          I wouldn't include this patch yet :-/

          If you happen to know why the dicts copied by foo.vim are not freed
          with the second version of my patch, that would be great. Else, I will
          take another look next weekend.

          Nico

          --~--~---------~--~----~------------~-------~--~----~
          You received this message from the "vim_dev" maillist.
          For more information, visit http://www.vim.org/maillist.php
          -~----------~----~----~----~------~----~------~--~---
        • Bram Moolenaar
          ... Here is a new patch that hopefully fixes both the crash and the leaks. It s a bit tricky, but I think this catches all situations. Please verify. Note that
          Message 4 of 12 , May 22, 2009
            Dominique Pelle wrote:

            > Nico Weber wrote:
            >
            > > Hi,
            > >
            > > On 03.05.2009, at 00:03, Dominique Pellé wrote:
            > >
            > >> After applying your patch, there are no such errors anymore.
            > >>
            > >> However, when exiting, I see that those blocks are not being
            > >> freed:
            > >>
            > >> ==16990== 217 bytes in 10 blocks are possibly lost in loss record 36
            > >> of 57
            > >> ==16990== at 0x402603E: malloc (vg_replace_malloc.c:207)
            > >> ==16990== by 0x81142FA: lalloc (misc2.c:866)
            > >> ==16990== by 0x8114216: alloc (misc2.c:765)
            > >> ==16990== by 0x807AD1D: dictitem_alloc (eval.c:6775)
            > >> ==16990== by 0x8074FFD: set_var_lval (eval.c:2856)
            > >> ==16990== by 0x80742F4: ex_let_one (eval.c:2414)
            > >> ==16990== by 0x807329F: ex_let_vars (eval.c:1869)
            > >> ==16990== by 0x8073250: ex_let (eval.c:1834)
            > >> ==16990== by 0x80A6AA3: do_one_cmd (ex_docmd.c:2622)
            > >> ==16990== by 0x80A4323: do_cmdline (ex_docmd.c:1096)
            > >> ==16990== by 0x8090328: call_user_func (eval.c:21301)
            > >> ==16990== by 0x807C4FE: call_func (eval.c:8079)
            > >> ==16990== by 0x807C142: get_func_tv (eval.c:7925)
            > >> ==16990== by 0x8075B83: ex_call (eval.c:3333)
            > >> ==16990== by 0x80A6AA3: do_one_cmd (ex_docmd.c:2622)
            > >> ==16990== by 0x80A4323: do_cmdline (ex_docmd.c:1096)
            > >> ==16990== by 0x812A758: nv_colon (normal.c:5227)
            > >> ==16990== by 0x8123DA2: normal_cmd (normal.c:1189)
            > >> ==16990== by 0x80E6D49: main_loop (main.c:1180)
            > >> ==16990== by 0x80E6896: main (main.c:939)
            > >>
            > >> I built Vim with -DEXITFREE (i.e. uncommented line
            > >> PROFILE_CFLAGS = -DEXITFREE in src/Makefile)
            > >> so normally all blocks should be freed when exiting.
            > >
            > > Thanks for checking.
            > >
            > > I've attached an updated version of the patch that fixes some of the
            > > leaks. The copy()d dicts in the script don't get freed, but I don't
            > > (yet?) understand why.
            > >
            > > Nico
            >
            >
            > I tried to fix the leak as well but without success so far.
            > It does not seem simple.
            >
            > In any cases, it's a real leak, running the following leak.vim
            > script for example causes Vim memory usage to grow
            > continuously:
            >
            > --- 8< --- cut here --- 8< --- cut here --- 8< ---
            > set nocp
            >
            > " foo.vim is the script attached in the original bug submission
            > " at http://groups.google.com/group/vim_mac/browse_thread/thread/4e0149ff4f84e3d3
            > so foo.vim
            >
            > let g:count_loops = 0
            > while 1
            > call foo#Buffer.New()
            > q
            > let g:count_loops = g:count_loops + 1
            > endwhile
            > --- 8< --- cut here --- 8< --- cut here --- 8< ---
            >
            > I do:
            >
            > $ vim -u NONE leak.vim
            > :so %
            >
            > Then in another xterm, I can see with "top" that memory usage
            > of Vim keeps increasing.
            >
            > If I run the leak.vim script with Valgrind...
            >
            > valgrind --leak-resolution=high --leak-check=yes \
            > --num-callers=30 --track-fds=yes 2> vg.log \
            > ./vim -u NONE leak.vim
            >
            > Then do:
            > - :so %
            > - let the script execute for some time
            > - press CTRL-C to interrupt the infinite loop
            > - Look at how many times loop iterated with
            > :echo g:count_loops
            > (it prints 2774 for example)
            > - then quit vim: qa!
            >
            > Then look for leaks in vg.log, and observe that some leaks
            > happen exactly 2774 times (same number as number as
            > g:loop_count):
            >
            > ==22962== 27,740 bytes in 2,774 blocks are possibly lost in loss
            > record 113 of 125
            > ==22962== at 0x402603E: malloc (vg_replace_malloc.c:207)
            > ==22962== by 0x81147FD: lalloc (misc2.c:866)
            > ==22962== by 0x8114708: alloc (misc2.c:765)
            > ==22962== by 0x8114C16: vim_strsave (misc2.c:1177)
            > ==22962== by 0x808C427: copy_tv (eval.c:19380)
            > ==22962== by 0x808AE51: get_var_tv (eval.c:18452)
            > ==22962== by 0x80785E7: eval7 (eval.c:5032)
            > ==22962== by 0x8077EA3: eval6 (eval.c:4685)
            > ==22962== by 0x8077A8F: eval5 (eval.c:4501)
            > ==22962== by 0x8076FE0: eval4 (eval.c:4196)
            > ==22962== by 0x8076E38: eval3 (eval.c:4108)
            > ==22962== by 0x8076CC4: eval2 (eval.c:4037)
            > ==22962== by 0x8076AF4: eval1 (eval.c:3962)
            > ==22962== by 0x8079667: get_list_tv (eval.c:5675)
            > ==22962== by 0x807837D: eval7 (eval.c:4943)
            > ==22962== by 0x8077EA3: eval6 (eval.c:4685)
            > ==22962== by 0x8077A8F: eval5 (eval.c:4501)
            > ==22962== by 0x8076FE0: eval4 (eval.c:4196)
            > ==22962== by 0x8076E38: eval3 (eval.c:4108)
            > ==22962== by 0x8076CC4: eval2 (eval.c:4037)
            > ==22962== by 0x8076AF4: eval1 (eval.c:3962)
            > ==22962== by 0x8076A5B: eval0 (eval.c:3919)
            > ==22962== by 0x807326C: ex_let (eval.c:1833)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
            > ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
            > ==22962== by 0x8090507: call_user_func (eval.c:21381)
            > ==22962== by 0x807C6DD: call_func (eval.c:8159)
            > ==22962== by 0x807C321: get_func_tv (eval.c:8005)
            > ==22962== by 0x8075C03: ex_call (eval.c:3341)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
            > ==22962==
            > ==22962==
            > ==22962== 33,288 bytes in 5,548 blocks are possibly lost in loss
            > record 114 of 125
            > ==22962== at 0x402603E: malloc (vg_replace_malloc.c:207)
            > ==22962== by 0x81147FD: lalloc (misc2.c:866)
            > ==22962== by 0x8114708: alloc (misc2.c:765)
            > ==22962== by 0x8114C16: vim_strsave (misc2.c:1177)
            > ==22962== by 0x808C427: copy_tv (eval.c:19380)
            > ==22962== by 0x807B117: dict_copy (eval.c:6961)
            > ==22962== by 0x808C662: item_copy (eval.c:19471)
            > ==22962== by 0x807DB82: f_copy (eval.c:9141)
            > ==22962== by 0x807C7DF: call_func (eval.c:8188)
            > ==22962== by 0x807C321: get_func_tv (eval.c:8005)
            > ==22962== by 0x807859A: eval7 (eval.c:5018)
            > ==22962== by 0x8077EA3: eval6 (eval.c:4685)
            > ==22962== by 0x8077A8F: eval5 (eval.c:4501)
            > ==22962== by 0x8076FE0: eval4 (eval.c:4196)
            > ==22962== by 0x8076E38: eval3 (eval.c:4108)
            > ==22962== by 0x8076CC4: eval2 (eval.c:4037)
            > ==22962== by 0x8076AF4: eval1 (eval.c:3962)
            > ==22962== by 0x8076A5B: eval0 (eval.c:3919)
            > ==22962== by 0x807326C: ex_let (eval.c:1833)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
            > ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
            > ==22962== by 0x8090507: call_user_func (eval.c:21381)
            > ==22962== by 0x807C6DD: call_func (eval.c:8159)
            > ==22962== by 0x807C321: get_func_tv (eval.c:8005)
            > ==22962== by 0x8075C03: ex_call (eval.c:3341)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
            > ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
            > ==22962== by 0x80A2793: do_source (ex_cmds2.c:3119)
            > ==22962== by 0x80A2047: cmd_source (ex_cmds2.c:2741)
            > ==22962== by 0x80A1F9B: ex_source (ex_cmds2.c:2714)
            > ==22962==
            > ==22962==
            > ==22962== 49,932 bytes in 8,322 blocks are possibly lost in loss
            > record 115 of 125
            > ==22962== at 0x402603E: malloc (vg_replace_malloc.c:207)
            > ==22962== by 0x81147FD: lalloc (misc2.c:866)
            > ==22962== by 0x8114708: alloc (misc2.c:765)
            > ==22962== by 0x8114C16: vim_strsave (misc2.c:1177)
            > ==22962== by 0x808C427: copy_tv (eval.c:19380)
            > ==22962== by 0x807B117: dict_copy (eval.c:6961)
            > ==22962== by 0x808C662: item_copy (eval.c:19471)
            > ==22962== by 0x807DB82: f_copy (eval.c:9141)
            > ==22962== by 0x807C7DF: call_func (eval.c:8188)
            > ==22962== by 0x807C321: get_func_tv (eval.c:8005)
            > ==22962== by 0x807859A: eval7 (eval.c:5018)
            > ==22962== by 0x8077EA3: eval6 (eval.c:4685)
            > ==22962== by 0x8077A8F: eval5 (eval.c:4501)
            > ==22962== by 0x8076FE0: eval4 (eval.c:4196)
            > ==22962== by 0x8076E38: eval3 (eval.c:4108)
            > ==22962== by 0x8076CC4: eval2 (eval.c:4037)
            > ==22962== by 0x8076AF4: eval1 (eval.c:3962)
            > ==22962== by 0x8076A5B: eval0 (eval.c:3919)
            > ==22962== by 0x807326C: ex_let (eval.c:1833)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
            > ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
            > ==22962== by 0x8090507: call_user_func (eval.c:21381)
            > ==22962== by 0x807C6DD: call_func (eval.c:8159)
            > ==22962== by 0x807C321: get_func_tv (eval.c:8005)
            > ==22962== by 0x808AF05: handle_subscript (eval.c:18491)
            > ==22962== by 0x8078640: eval7 (eval.c:5046)
            > ==22962== by 0x8077EA3: eval6 (eval.c:4685)
            > ==22962== by 0x8077A8F: eval5 (eval.c:4501)
            > ==22962== by 0x8076FE0: eval4 (eval.c:4196)
            > ==22962== by 0x8076E38: eval3 (eval.c:4108)
            > ==22962==
            > ==22962==
            > ==22962== 58,254 bytes in 2,774 blocks are possibly lost in loss
            > record 116 of 125
            > ==22962== at 0x402603E: malloc (vg_replace_malloc.c:207)
            > ==22962== by 0x81147FD: lalloc (misc2.c:866)
            > ==22962== by 0x8114708: alloc (misc2.c:765)
            > ==22962== by 0x807AEFC: dictitem_alloc (eval.c:6855)
            > ==22962== by 0x807507D: set_var_lval (eval.c:2864)
            > ==22962== by 0x8074374: ex_let_one (eval.c:2422)
            > ==22962== by 0x807331F: ex_let_vars (eval.c:1877)
            > ==22962== by 0x80732D0: ex_let (eval.c:1842)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
            > ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
            > ==22962== by 0x8090507: call_user_func (eval.c:21381)
            > ==22962== by 0x807C6DD: call_func (eval.c:8159)
            > ==22962== by 0x807C321: get_func_tv (eval.c:8005)
            > ==22962== by 0x8075C03: ex_call (eval.c:3341)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
            > ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
            > ==22962== by 0x8090507: call_user_func (eval.c:21381)
            > ==22962== by 0x807C6DD: call_func (eval.c:8159)
            > ==22962== by 0x807C321: get_func_tv (eval.c:8005)
            > ==22962== by 0x8075C03: ex_call (eval.c:3341)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
            > ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
            > ==22962== by 0x80A2793: do_source (ex_cmds2.c:3119)
            > ==22962== by 0x80A2047: cmd_source (ex_cmds2.c:2741)
            > ==22962== by 0x80A1F9B: ex_source (ex_cmds2.c:2714)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
            > ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
            > ==22962== by 0x812ACC4: nv_colon (normal.c:5227)
            > ==22962== by 0x812430E: normal_cmd (normal.c:1189)
            > ==22962== by 0x80E6F3D: main_loop (main.c:1180)
            > ==22962==
            > ==22962==
            > ==22962== 77,672 bytes in 2,774 blocks are possibly lost in loss
            > record 117 of 125
            > ==22962== at 0x402603E: malloc (vg_replace_malloc.c:207)
            > ==22962== by 0x81147FD: lalloc (misc2.c:866)
            > ==22962== by 0x8114708: alloc (misc2.c:765)
            > ==22962== by 0x807AEFC: dictitem_alloc (eval.c:6855)
            > ==22962== by 0x807507D: set_var_lval (eval.c:2864)
            > ==22962== by 0x8074374: ex_let_one (eval.c:2422)
            > ==22962== by 0x807331F: ex_let_vars (eval.c:1877)
            > ==22962== by 0x80732D0: ex_let (eval.c:1842)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
            > ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
            > ==22962== by 0x8090507: call_user_func (eval.c:21381)
            > ==22962== by 0x807C6DD: call_func (eval.c:8159)
            > ==22962== by 0x807C321: get_func_tv (eval.c:8005)
            > ==22962== by 0x808AF05: handle_subscript (eval.c:18491)
            > ==22962== by 0x8078640: eval7 (eval.c:5046)
            > ==22962== by 0x8077EA3: eval6 (eval.c:4685)
            > ==22962== by 0x8077A8F: eval5 (eval.c:4501)
            > ==22962== by 0x8076FE0: eval4 (eval.c:4196)
            > ==22962== by 0x8076E38: eval3 (eval.c:4108)
            > ==22962== by 0x8076CC4: eval2 (eval.c:4037)
            > ==22962== by 0x8076AF4: eval1 (eval.c:3962)
            > ==22962== by 0x8076A5B: eval0 (eval.c:3919)
            > ==22962== by 0x807326C: ex_let (eval.c:1833)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
            > ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
            > ==22962== by 0x8090507: call_user_func (eval.c:21381)
            > ==22962== by 0x807C6DD: call_func (eval.c:8159)
            > ==22962== by 0x807C321: get_func_tv (eval.c:8005)
            > ==22962== by 0x8075C03: ex_call (eval.c:3341)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
            > ==22962==
            > ==22962==
            > ==22962== 133,152 bytes in 5,548 blocks are possibly lost in loss
            > record 118 of 125
            > ==22962== at 0x402603E: malloc (vg_replace_malloc.c:207)
            > ==22962== by 0x81147FD: lalloc (misc2.c:866)
            > ==22962== by 0x8114708: alloc (misc2.c:765)
            > ==22962== by 0x807AEFC: dictitem_alloc (eval.c:6855)
            > ==22962== by 0x807B0B3: dict_copy (eval.c:6948)
            > ==22962== by 0x808C662: item_copy (eval.c:19471)
            > ==22962== by 0x807DB82: f_copy (eval.c:9141)
            > ==22962== by 0x807C7DF: call_func (eval.c:8188)
            > ==22962== by 0x807C321: get_func_tv (eval.c:8005)
            > ==22962== by 0x807859A: eval7 (eval.c:5018)
            > ==22962== by 0x8077EA3: eval6 (eval.c:4685)
            > ==22962== by 0x8077A8F: eval5 (eval.c:4501)
            > ==22962== by 0x8076FE0: eval4 (eval.c:4196)
            > ==22962== by 0x8076E38: eval3 (eval.c:4108)
            > ==22962== by 0x8076CC4: eval2 (eval.c:4037)
            > ==22962== by 0x8076AF4: eval1 (eval.c:3962)
            > ==22962== by 0x8076A5B: eval0 (eval.c:3919)
            > ==22962== by 0x807326C: ex_let (eval.c:1833)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
            > ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
            > ==22962== by 0x8090507: call_user_func (eval.c:21381)
            > ==22962== by 0x807C6DD: call_func (eval.c:8159)
            > ==22962== by 0x807C321: get_func_tv (eval.c:8005)
            > ==22962== by 0x8075C03: ex_call (eval.c:3341)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
            > ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
            > ==22962== by 0x80A2793: do_source (ex_cmds2.c:3119)
            > ==22962== by 0x80A2047: cmd_source (ex_cmds2.c:2741)
            > ==22962== by 0x80A1F9B: ex_source (ex_cmds2.c:2714)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
            > ==22962==
            > ==22962==
            > ==22962== 160,892 bytes in 5,548 blocks are possibly lost in loss
            > record 119 of 125
            > ==22962== at 0x402603E: malloc (vg_replace_malloc.c:207)
            > ==22962== by 0x81147FD: lalloc (misc2.c:866)
            > ==22962== by 0x8114708: alloc (misc2.c:765)
            > ==22962== by 0x807AEFC: dictitem_alloc (eval.c:6855)
            > ==22962== by 0x807507D: set_var_lval (eval.c:2864)
            > ==22962== by 0x8074374: ex_let_one (eval.c:2422)
            > ==22962== by 0x807331F: ex_let_vars (eval.c:1877)
            > ==22962== by 0x80732D0: ex_let (eval.c:1842)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
            > ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
            > ==22962== by 0x8090507: call_user_func (eval.c:21381)
            > ==22962== by 0x807C6DD: call_func (eval.c:8159)
            > ==22962== by 0x807C321: get_func_tv (eval.c:8005)
            > ==22962== by 0x8075C03: ex_call (eval.c:3341)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
            > ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
            > ==22962== by 0x80A2793: do_source (ex_cmds2.c:3119)
            > ==22962== by 0x80A2047: cmd_source (ex_cmds2.c:2741)
            > ==22962== by 0x80A1F9B: ex_source (ex_cmds2.c:2714)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
            > ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
            > ==22962== by 0x812ACC4: nv_colon (normal.c:5227)
            > ==22962== by 0x812430E: normal_cmd (normal.c:1189)
            > ==22962== by 0x80E6F3D: main_loop (main.c:1180)
            > ==22962== by 0x80E6A8A: main (main.c:939)
            > ==22962==
            > ==22962==
            > ==22962== 213,598 bytes in 8,322 blocks are possibly lost in loss
            > record 120 of 125
            > ==22962== at 0x402603E: malloc (vg_replace_malloc.c:207)
            > ==22962== by 0x81147FD: lalloc (misc2.c:866)
            > ==22962== by 0x8114708: alloc (misc2.c:765)
            > ==22962== by 0x807AEFC: dictitem_alloc (eval.c:6855)
            > ==22962== by 0x807B0B3: dict_copy (eval.c:6948)
            > ==22962== by 0x808C662: item_copy (eval.c:19471)
            > ==22962== by 0x807DB82: f_copy (eval.c:9141)
            > ==22962== by 0x807C7DF: call_func (eval.c:8188)
            > ==22962== by 0x807C321: get_func_tv (eval.c:8005)
            > ==22962== by 0x807859A: eval7 (eval.c:5018)
            > ==22962== by 0x8077EA3: eval6 (eval.c:4685)
            > ==22962== by 0x8077A8F: eval5 (eval.c:4501)
            > ==22962== by 0x8076FE0: eval4 (eval.c:4196)
            > ==22962== by 0x8076E38: eval3 (eval.c:4108)
            > ==22962== by 0x8076CC4: eval2 (eval.c:4037)
            > ==22962== by 0x8076AF4: eval1 (eval.c:3962)
            > ==22962== by 0x8076A5B: eval0 (eval.c:3919)
            > ==22962== by 0x807326C: ex_let (eval.c:1833)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
            > ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
            > ==22962== by 0x8090507: call_user_func (eval.c:21381)
            > ==22962== by 0x807C6DD: call_func (eval.c:8159)
            > ==22962== by 0x807C321: get_func_tv (eval.c:8005)
            > ==22962== by 0x808AF05: handle_subscript (eval.c:18491)
            > ==22962== by 0x8078640: eval7 (eval.c:5046)
            > ==22962== by 0x8077EA3: eval6 (eval.c:4685)
            > ==22962== by 0x8077A8F: eval5 (eval.c:4501)
            > ==22962== by 0x8076FE0: eval4 (eval.c:4196)
            > ==22962== by 0x8076E38: eval3 (eval.c:4108)
            > ==22962== by 0x8076CC4: eval2 (eval.c:4037)
            > ==22962==
            > ==22962==
            > ==22962== 288,496 bytes in 5,548 blocks are possibly lost in loss
            > record 121 of 125
            > ==22962== at 0x402603E: malloc (vg_replace_malloc.c:207)
            > ==22962== by 0x81147FD: lalloc (misc2.c:866)
            > ==22962== by 0x8114723: alloc_clear (misc2.c:777)
            > ==22962== by 0x80797D0: list_alloc (eval.c:5729)
            > ==22962== by 0x807961D: get_list_tv (eval.c:5667)
            > ==22962== by 0x807837D: eval7 (eval.c:4943)
            > ==22962== by 0x8077EA3: eval6 (eval.c:4685)
            > ==22962== by 0x8077A8F: eval5 (eval.c:4501)
            > ==22962== by 0x8076FE0: eval4 (eval.c:4196)
            > ==22962== by 0x8076E38: eval3 (eval.c:4108)
            > ==22962== by 0x8076CC4: eval2 (eval.c:4037)
            > ==22962== by 0x8076AF4: eval1 (eval.c:3962)
            > ==22962== by 0x8076A5B: eval0 (eval.c:3919)
            > ==22962== by 0x807326C: ex_let (eval.c:1833)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
            > ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
            > ==22962== by 0x8090507: call_user_func (eval.c:21381)
            > ==22962== by 0x807C6DD: call_func (eval.c:8159)
            > ==22962== by 0x807C321: get_func_tv (eval.c:8005)
            > ==22962== by 0x8075C03: ex_call (eval.c:3341)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
            > ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
            > ==22962== by 0x8090507: call_user_func (eval.c:21381)
            > ==22962== by 0x807C6DD: call_func (eval.c:8159)
            > ==22962== by 0x807C321: get_func_tv (eval.c:8005)
            > ==22962== by 0x8075C03: ex_call (eval.c:3341)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
            > ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
            > ==22962== by 0x80A2793: do_source (ex_cmds2.c:3119)
            > ==22962== by 0x80A2047: cmd_source (ex_cmds2.c:2741)
            > ==22962==
            > ==22962==
            > ==22962== 399,456 bytes in 16,644 blocks are possibly lost in loss
            > record 122 of 125
            > ==22962== at 0x402603E: malloc (vg_replace_malloc.c:207)
            > ==22962== by 0x81147FD: lalloc (misc2.c:866)
            > ==22962== by 0x8114708: alloc (misc2.c:765)
            > ==22962== by 0x807994D: listitem_alloc (eval.c:5810)
            > ==22962== by 0x807967A: get_list_tv (eval.c:5679)
            > ==22962== by 0x807837D: eval7 (eval.c:4943)
            > ==22962== by 0x8077EA3: eval6 (eval.c:4685)
            > ==22962== by 0x8077A8F: eval5 (eval.c:4501)
            > ==22962== by 0x8076FE0: eval4 (eval.c:4196)
            > ==22962== by 0x8076E38: eval3 (eval.c:4108)
            > ==22962== by 0x8076CC4: eval2 (eval.c:4037)
            > ==22962== by 0x8076AF4: eval1 (eval.c:3962)
            > ==22962== by 0x8076A5B: eval0 (eval.c:3919)
            > ==22962== by 0x807326C: ex_let (eval.c:1833)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
            > ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
            > ==22962== by 0x8090507: call_user_func (eval.c:21381)
            > ==22962== by 0x807C6DD: call_func (eval.c:8159)
            > ==22962== by 0x807C321: get_func_tv (eval.c:8005)
            > ==22962== by 0x8075C03: ex_call (eval.c:3341)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
            > ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
            > ==22962== by 0x8090507: call_user_func (eval.c:21381)
            > ==22962== by 0x807C6DD: call_func (eval.c:8159)
            > ==22962== by 0x807C321: get_func_tv (eval.c:8005)
            > ==22962== by 0x8075C03: ex_call (eval.c:3341)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
            > ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
            > ==22962== by 0x80A2793: do_source (ex_cmds2.c:3119)
            > ==22962== by 0x80A2047: cmd_source (ex_cmds2.c:2741)
            > ==22962==
            > ==22962==
            > ==22962== 499,320 bytes in 2,774 blocks are possibly lost in loss
            > record 123 of 125
            > ==22962== at 0x402603E: malloc (vg_replace_malloc.c:207)
            > ==22962== by 0x81147FD: lalloc (misc2.c:866)
            > ==22962== by 0x8114708: alloc (misc2.c:765)
            > ==22962== by 0x807AD1E: dict_alloc (eval.c:6770)
            > ==22962== by 0x807B6A8: get_dict_tv (eval.c:7216)
            > ==22962== by 0x807839E: eval7 (eval.c:4949)
            > ==22962== by 0x8077EA3: eval6 (eval.c:4685)
            > ==22962== by 0x8077A8F: eval5 (eval.c:4501)
            > ==22962== by 0x8076FE0: eval4 (eval.c:4196)
            > ==22962== by 0x8076E38: eval3 (eval.c:4108)
            > ==22962== by 0x8076CC4: eval2 (eval.c:4037)
            > ==22962== by 0x8076AF4: eval1 (eval.c:3962)
            > ==22962== by 0x8076A5B: eval0 (eval.c:3919)
            > ==22962== by 0x807326C: ex_let (eval.c:1833)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
            > ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
            > ==22962== by 0x8090507: call_user_func (eval.c:21381)
            > ==22962== by 0x807C6DD: call_func (eval.c:8159)
            > ==22962== by 0x807C321: get_func_tv (eval.c:8005)
            > ==22962== by 0x808AF05: handle_subscript (eval.c:18491)
            > ==22962== by 0x8078640: eval7 (eval.c:5046)
            > ==22962== by 0x8077EA3: eval6 (eval.c:4685)
            > ==22962== by 0x8077A8F: eval5 (eval.c:4501)
            > ==22962== by 0x8076FE0: eval4 (eval.c:4196)
            > ==22962== by 0x8076E38: eval3 (eval.c:4108)
            > ==22962== by 0x8076CC4: eval2 (eval.c:4037)
            > ==22962== by 0x8076AF4: eval1 (eval.c:3962)
            > ==22962== by 0x8076A5B: eval0 (eval.c:3919)
            > ==22962== by 0x807326C: ex_let (eval.c:1833)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
            > ==22962==
            > ==22962==
            > ==22962== 499,320 bytes in 2,774 blocks are possibly lost in loss
            > record 124 of 125
            > ==22962== at 0x402603E: malloc (vg_replace_malloc.c:207)
            > ==22962== by 0x81147FD: lalloc (misc2.c:866)
            > ==22962== by 0x8114708: alloc (misc2.c:765)
            > ==22962== by 0x807AD1E: dict_alloc (eval.c:6770)
            > ==22962== by 0x807B040: dict_copy (eval.c:6933)
            > ==22962== by 0x808C662: item_copy (eval.c:19471)
            > ==22962== by 0x807DB82: f_copy (eval.c:9141)
            > ==22962== by 0x807C7DF: call_func (eval.c:8188)
            > ==22962== by 0x807C321: get_func_tv (eval.c:8005)
            > ==22962== by 0x807859A: eval7 (eval.c:5018)
            > ==22962== by 0x8077EA3: eval6 (eval.c:4685)
            > ==22962== by 0x8077A8F: eval5 (eval.c:4501)
            > ==22962== by 0x8076FE0: eval4 (eval.c:4196)
            > ==22962== by 0x8076E38: eval3 (eval.c:4108)
            > ==22962== by 0x8076CC4: eval2 (eval.c:4037)
            > ==22962== by 0x8076AF4: eval1 (eval.c:3962)
            > ==22962== by 0x8076A5B: eval0 (eval.c:3919)
            > ==22962== by 0x807326C: ex_let (eval.c:1833)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
            > ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
            > ==22962== by 0x8090507: call_user_func (eval.c:21381)
            > ==22962== by 0x807C6DD: call_func (eval.c:8159)
            > ==22962== by 0x807C321: get_func_tv (eval.c:8005)
            > ==22962== by 0x808AF05: handle_subscript (eval.c:18491)
            > ==22962== by 0x8078640: eval7 (eval.c:5046)
            > ==22962== by 0x8077EA3: eval6 (eval.c:4685)
            > ==22962== by 0x8077A8F: eval5 (eval.c:4501)
            > ==22962== by 0x8076FE0: eval4 (eval.c:4196)
            > ==22962== by 0x8076E38: eval3 (eval.c:4108)
            > ==22962== by 0x8076CC4: eval2 (eval.c:4037)
            > ==22962==
            > ==22962==
            > ==22962== 499,320 bytes in 2,774 blocks are possibly lost in loss
            > record 125 of 125
            > ==22962== at 0x402603E: malloc (vg_replace_malloc.c:207)
            > ==22962== by 0x81147FD: lalloc (misc2.c:866)
            > ==22962== by 0x8114708: alloc (misc2.c:765)
            > ==22962== by 0x807AD1E: dict_alloc (eval.c:6770)
            > ==22962== by 0x807B040: dict_copy (eval.c:6933)
            > ==22962== by 0x808C662: item_copy (eval.c:19471)
            > ==22962== by 0x807DB82: f_copy (eval.c:9141)
            > ==22962== by 0x807C7DF: call_func (eval.c:8188)
            > ==22962== by 0x807C321: get_func_tv (eval.c:8005)
            > ==22962== by 0x807859A: eval7 (eval.c:5018)
            > ==22962== by 0x8077EA3: eval6 (eval.c:4685)
            > ==22962== by 0x8077A8F: eval5 (eval.c:4501)
            > ==22962== by 0x8076FE0: eval4 (eval.c:4196)
            > ==22962== by 0x8076E38: eval3 (eval.c:4108)
            > ==22962== by 0x8076CC4: eval2 (eval.c:4037)
            > ==22962== by 0x8076AF4: eval1 (eval.c:3962)
            > ==22962== by 0x8076A5B: eval0 (eval.c:3919)
            > ==22962== by 0x807326C: ex_let (eval.c:1833)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
            > ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
            > ==22962== by 0x8090507: call_user_func (eval.c:21381)
            > ==22962== by 0x807C6DD: call_func (eval.c:8159)
            > ==22962== by 0x807C321: get_func_tv (eval.c:8005)
            > ==22962== by 0x8075C03: ex_call (eval.c:3341)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
            > ==22962== by 0x80A450B: do_cmdline (ex_docmd.c:1096)
            > ==22962== by 0x80A2793: do_source (ex_cmds2.c:3119)
            > ==22962== by 0x80A2047: cmd_source (ex_cmds2.c:2741)
            > ==22962== by 0x80A1F9B: ex_source (ex_cmds2.c:2714)
            > ==22962== by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)

            Here is a new patch that hopefully fixes both the crash and the leaks.
            It's a bit tricky, but I think this catches all situations.
            Please verify.

            Note that with your script one needs to wait a few moments before
            exiting to give the garbage collector a chance.


            *** ../vim-7.2.185/src/eval.c 2009-05-16 17:29:37.000000000 +0200
            --- src/eval.c 2009-05-22 20:04:22.000000000 +0200
            ***************
            *** 129,136 ****
            --- 129,139 ----
            /*
            * When recursively copying lists and dicts we need to remember which ones we
            * have done to avoid endless recursiveness. This unique ID is used for that.
            + * The last bit is used for previous_funccal, ignored when comparing.
            */
            static int current_copyID = 0;
            + #define COPYID_INC 2
            + #define COPYID_MASK (~0x1)

            /*
            * Array to hold the hashtab with variables local to each sourced script.
            ***************
            *** 439,444 ****
            --- 442,448 ----
            static void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2));
            static char_u *list2string __ARGS((typval_T *tv, int copyID));
            static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo, int copyID));
            + static int free_unref_items __ARGS((int copyID));
            static void set_ref_in_ht __ARGS((hashtab_T *ht, int copyID));
            static void set_ref_in_list __ARGS((list_T *l, int copyID));
            static void set_ref_in_item __ARGS((typval_T *tv, int copyID));
            ***************
            *** 6494,6507 ****
            int
            garbage_collect()
            {
            ! dict_T *dd;
            ! list_T *ll;
            ! int copyID = ++current_copyID;
            buf_T *buf;
            win_T *wp;
            int i;
            funccall_T *fc, **pfc;
            ! int did_free = FALSE;
            #ifdef FEAT_WINDOWS
            tabpage_T *tp;
            #endif
            --- 6498,6510 ----
            int
            garbage_collect()
            {
            ! int copyID;
            buf_T *buf;
            win_T *wp;
            int i;
            funccall_T *fc, **pfc;
            ! int did_free;
            ! int did_free_funccal = FALSE;
            #ifdef FEAT_WINDOWS
            tabpage_T *tp;
            #endif
            ***************
            *** 6511,6520 ****
            --- 6514,6538 ----
            may_garbage_collect = FALSE;
            garbage_collect_at_exit = FALSE;

            + /* We advance by two because we add one for items referenced through
            + * previous_funccal. */
            + current_copyID += COPYID_INC;
            + copyID = current_copyID;
            +
            /*
            * 1. Go through all accessible variables and mark all lists and dicts
            * with copyID.
            */
            +
            + /* Don't free variables in the previous_funccal list unless they are only
            + * referenced through previous_funccal. This must be first, because if
            + * the item is referenced elsewhere it must not be freed. */
            + for (fc = previous_funccal; fc != NULL; fc = fc->caller)
            + {
            + set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID + 1);
            + set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID + 1);
            + }
            +
            /* script-local variables */
            for (i = 1; i <= ga_scripts.ga_len; ++i)
            set_ref_in_ht(&SCRIPT_VARS(i), copyID);
            ***************
            *** 6546,6556 ****
            /* v: vars */
            set_ref_in_ht(&vimvarht, copyID);

            /*
            ! * 2. Go through the list of dicts and free items without the copyID.
            */
            for (dd = first_dict; dd != NULL; )
            ! if (dd->dv_copyID != copyID)
            {
            /* Free the Dictionary and ordinary items it contains, but don't
            * recurse into Lists and Dictionaries, they will be in the list
            --- 6564,6610 ----
            /* v: vars */
            set_ref_in_ht(&vimvarht, copyID);

            + /* Free lists and dictionaries that are not referenced. */
            + did_free = free_unref_items(copyID);
            +
            + /* 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;
            + did_free_funccal = TRUE;
            + }
            + else
            + pfc = &(*pfc)->caller;
            + }
            + if (did_free_funccal)
            + /* When a funccal was freed some more items might be garbage
            + * collected, so run again. */
            + (void)garbage_collect();
            +
            + return did_free;
            + }
            +
            + /*
            + * Free lists and dictionaries that are no longer referenced.
            + */
            + static int
            + free_unref_items(copyID)
            + int copyID;
            + {
            + dict_T *dd;
            + list_T *ll;
            + int did_free = FALSE;
            +
            /*
            ! * Go through the list of dicts and free items without the copyID.
            */
            for (dd = first_dict; dd != NULL; )
            ! if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK))
            {
            /* Free the Dictionary and ordinary items it contains, but don't
            * recurse into Lists and Dictionaries, they will be in the list
            ***************
            *** 6565,6576 ****
            dd = dd->dv_used_next;

            /*
            ! * 3. Go through the list of lists and free items without the copyID.
            ! * But don't free a list that has a watcher (used in a for loop), these
            ! * are not referenced anywhere.
            */
            for (ll = first_list; ll != NULL; )
            ! if (ll->lv_copyID != copyID && ll->lv_watch == NULL)
            {
            /* Free the List and ordinary items it contains, but don't recurse
            * into Lists and Dictionaries, they will be in the list of dicts
            --- 6619,6631 ----
            dd = dd->dv_used_next;

            /*
            ! * Go through the list of lists and free items without the copyID.
            ! * But don't free a list that has a watcher (used in a for loop), these
            ! * are not referenced anywhere.
            */
            for (ll = first_list; ll != NULL; )
            ! if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)
            ! && ll->lv_watch == NULL)
            {
            /* Free the List and ordinary items it contains, but don't recurse
            * into Lists and Dictionaries, they will be in the list of dicts
            ***************
            *** 6584,6603 ****
            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;
            }

            --- 6639,6644 ----
            ***************
            *** 18842,18847 ****
            --- 18883,18889 ----
            {
            hash_init(&dict->dv_hashtab);
            dict->dv_refcount = DO_NOT_FREE_CNT;
            + dict->dv_copyID = 0;
            dict_var->di_tv.vval.v_dict = dict;
            dict_var->di_tv.v_type = VAR_DICT;
            dict_var->di_tv.v_lock = VAR_FIXED;
            ***************
            *** 21294,21301 ****
            current_funccal = fc->caller;
            --depth;

            ! /* if the a:000 list and the a: dict are not referenced we can free the
            ! * funccall_T and what's in it. */
            if (fc->l_varlist.lv_refcount == DO_NOT_FREE_CNT
            && fc->l_vars.dv_refcount == DO_NOT_FREE_CNT
            && fc->l_avars.dv_refcount == DO_NOT_FREE_CNT)
            --- 21336,21343 ----
            current_funccal = fc->caller;
            --depth;

            ! /* If the a:000 list and the l: and a: dicts are not referenced we can
            ! * free the funccall_T and what's in it. */
            if (fc->l_varlist.lv_refcount == DO_NOT_FREE_CNT
            && fc->l_vars.dv_refcount == DO_NOT_FREE_CNT
            && fc->l_avars.dv_refcount == DO_NOT_FREE_CNT)
            ***************
            *** 21334,21340 ****

            /*
            * Return TRUE if items in "fc" do not have "copyID". That means they are not
            ! * referenced from anywhere.
            */
            static int
            can_free_funccal(fc, copyID)
            --- 21376,21382 ----

            /*
            * Return TRUE if items in "fc" do not have "copyID". That means they are not
            ! * referenced from anywhere that is in use.
            */
            static int
            can_free_funccal(fc, copyID)


            --
            Why I like vim:
            > I like VIM because, when I ask a question in this newsgroup, I get a
            > one-line answer. With xemacs, I get a 1Kb lisp script with bugs in it ;-)

            /// Bram Moolenaar -- Bram@... -- 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
            -~----------~----~----~----~------~----~------~--~---
          • Nico Weber
            ... LGTM. Thanks for taking a look at this. I ran the offending script with and without this patch under valgrind, the patch seems to remove the double free
            Message 5 of 12 , May 23, 2009
              On 22.05.2009, at 11:20, Bram Moolenaar wrote:

              > Here is a new patch that hopefully fixes both the crash and the leaks.
              > It's a bit tricky, but I think this catches all situations.
              > Please verify.
              >
              > Note that with your script one needs to wait a few moments before
              > exiting to give the garbage collector a chance.

              LGTM. Thanks for taking a look at this.

              I ran the offending script with and without this patch under valgrind,
              the patch seems to remove the double free without introducing a memory
              leak. Should there be a testcase for this in the test files?

              Nit: garbage_collect() now contains a single step labeled "1." --
              perhaps get rid of the number?

              Nico


              --~--~---------~--~----~------------~-------~--~----~
              You received this message from the "vim_dev" maillist.
              For more information, visit http://www.vim.org/maillist.php
              -~----------~----~----~----~------~----~------~--~---
            • Bram Moolenaar
              ... There should be. Care to write one? ... I already sent out the patch. I ll adjust the comments and send it out later. -- ARTHUR: Be quiet! I order
              Message 6 of 12 , May 24, 2009
                Nico Weber wrote:

                > On 22.05.2009, at 11:20, Bram Moolenaar wrote:
                >
                > > Here is a new patch that hopefully fixes both the crash and the leaks.
                > > It's a bit tricky, but I think this catches all situations.
                > > Please verify.
                > >
                > > Note that with your script one needs to wait a few moments before
                > > exiting to give the garbage collector a chance.
                >
                > LGTM. Thanks for taking a look at this.
                >
                > I ran the offending script with and without this patch under valgrind,
                > the patch seems to remove the double free without introducing a memory
                > leak. Should there be a testcase for this in the test files?

                There should be. Care to write one?

                > Nit: garbage_collect() now contains a single step labeled "1." --
                > perhaps get rid of the number?

                I already sent out the patch. I'll adjust the comments and send it out
                later.

                --
                ARTHUR: Be quiet! I order you to shut up.
                OLD WOMAN: Order, eh -- who does he think he is?
                ARTHUR: I am your king!
                OLD WOMAN: Well, I didn't vote for you.
                "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

                /// Bram Moolenaar -- Bram@... -- 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
                -~----------~----~----~----~------~----~------~--~---
              • Kent Sibilev
                ... With this patch applied MacVim still crashes for me. Note that it doesn t do that if I instead apply the second Nico s patch. These are details of from
                Message 7 of 12 , May 27, 2009
                  2009/5/22 Bram Moolenaar <Bram@...>:
                  >
                  >
                  > Dominique Pelle wrote:
                  >
                  >> Nico Weber wrote:
                  >>
                  >> > Hi,
                  >> >
                  >> > On 03.05.2009, at 00:03, Dominique Pellé wrote:
                  >> >
                  >> >> After applying your patch, there are no such errors anymore.
                  >> >>
                  >> >> However, when exiting, I see that those blocks are not being
                  >> >> freed:
                  >> >>
                  >> >> ==16990== 217 bytes in 10 blocks are possibly lost in loss record 36
                  >> >> of 57
                  >> >> ==16990==    at 0x402603E: malloc (vg_replace_malloc.c:207)
                  >> >> ==16990==    by 0x81142FA: lalloc (misc2.c:866)
                  >> >> ==16990==    by 0x8114216: alloc (misc2.c:765)
                  >> >> ==16990==    by 0x807AD1D: dictitem_alloc (eval.c:6775)
                  >> >> ==16990==    by 0x8074FFD: set_var_lval (eval.c:2856)
                  >> >> ==16990==    by 0x80742F4: ex_let_one (eval.c:2414)
                  >> >> ==16990==    by 0x807329F: ex_let_vars (eval.c:1869)
                  >> >> ==16990==    by 0x8073250: ex_let (eval.c:1834)
                  >> >> ==16990==    by 0x80A6AA3: do_one_cmd (ex_docmd.c:2622)
                  >> >> ==16990==    by 0x80A4323: do_cmdline (ex_docmd.c:1096)
                  >> >> ==16990==    by 0x8090328: call_user_func (eval.c:21301)
                  >> >> ==16990==    by 0x807C4FE: call_func (eval.c:8079)
                  >> >> ==16990==    by 0x807C142: get_func_tv (eval.c:7925)
                  >> >> ==16990==    by 0x8075B83: ex_call (eval.c:3333)
                  >> >> ==16990==    by 0x80A6AA3: do_one_cmd (ex_docmd.c:2622)
                  >> >> ==16990==    by 0x80A4323: do_cmdline (ex_docmd.c:1096)
                  >> >> ==16990==    by 0x812A758: nv_colon (normal.c:5227)
                  >> >> ==16990==    by 0x8123DA2: normal_cmd (normal.c:1189)
                  >> >> ==16990==    by 0x80E6D49: main_loop (main.c:1180)
                  >> >> ==16990==    by 0x80E6896: main (main.c:939)
                  >> >>
                  >> >> I built Vim with -DEXITFREE (i.e. uncommented line
                  >> >> PROFILE_CFLAGS = -DEXITFREE  in src/Makefile)
                  >> >> so normally all blocks should be freed when exiting.
                  >> >
                  >> > Thanks for checking.
                  >> >
                  >> > I've attached an updated version of the patch that fixes some of the
                  >> > leaks. The copy()d dicts in the script don't get freed, but I don't
                  >> > (yet?) understand why.
                  >> >
                  >> > Nico
                  >>
                  >>
                  >> I tried to fix the leak as well but without success so far.
                  >> It does not seem simple.
                  >>
                  >> In any cases, it's a real leak, running the following leak.vim
                  >> script for example causes Vim memory usage to grow
                  >> continuously:
                  >>
                  >> --- 8< --- cut here --- 8< --- cut here --- 8< ---
                  >> set nocp
                  >>
                  >> " foo.vim is the script attached in the original bug submission
                  >> " at http://groups.google.com/group/vim_mac/browse_thread/thread/4e0149ff4f84e3d3
                  >> so foo.vim
                  >>
                  >> let g:count_loops = 0
                  >> while 1
                  >>   call foo#Buffer.New()
                  >>   q
                  >>   let g:count_loops = g:count_loops + 1
                  >> endwhile
                  >> --- 8< --- cut here --- 8< --- cut here --- 8< ---
                  >>
                  >> I do:
                  >>
                  >> $ vim -u NONE leak.vim
                  >> :so %
                  >>
                  >> Then in another xterm, I can see with "top" that memory usage
                  >> of Vim keeps increasing.
                  >>
                  >> If I run the leak.vim script with Valgrind...
                  >>
                  >> valgrind --leak-resolution=high --leak-check=yes \
                  >>     --num-callers=30 --track-fds=yes 2> vg.log \
                  >>    ./vim -u NONE leak.vim
                  >>
                  >> Then do:
                  >> - :so %
                  >> - let the script execute for some time
                  >> - press CTRL-C to interrupt the infinite loop
                  >> - Look at how many times loop iterated with
                  >>    :echo g:count_loops
                  >>   (it prints 2774 for example)
                  >> - then quit vim: qa!
                  >>
                  >> Then look for leaks in vg.log, and observe that some leaks
                  >> happen exactly 2774 times (same number as number as
                  >> g:loop_count):
                  >>
                  >> ==22962== 27,740 bytes in 2,774 blocks are possibly lost in loss
                  >> record 113 of 125
                  >> ==22962==    at 0x402603E: malloc (vg_replace_malloc.c:207)
                  >> ==22962==    by 0x81147FD: lalloc (misc2.c:866)
                  >> ==22962==    by 0x8114708: alloc (misc2.c:765)
                  >> ==22962==    by 0x8114C16: vim_strsave (misc2.c:1177)
                  >> ==22962==    by 0x808C427: copy_tv (eval.c:19380)
                  >> ==22962==    by 0x808AE51: get_var_tv (eval.c:18452)
                  >> ==22962==    by 0x80785E7: eval7 (eval.c:5032)
                  >> ==22962==    by 0x8077EA3: eval6 (eval.c:4685)
                  >> ==22962==    by 0x8077A8F: eval5 (eval.c:4501)
                  >> ==22962==    by 0x8076FE0: eval4 (eval.c:4196)
                  >> ==22962==    by 0x8076E38: eval3 (eval.c:4108)
                  >> ==22962==    by 0x8076CC4: eval2 (eval.c:4037)
                  >> ==22962==    by 0x8076AF4: eval1 (eval.c:3962)
                  >> ==22962==    by 0x8079667: get_list_tv (eval.c:5675)
                  >> ==22962==    by 0x807837D: eval7 (eval.c:4943)
                  >> ==22962==    by 0x8077EA3: eval6 (eval.c:4685)
                  >> ==22962==    by 0x8077A8F: eval5 (eval.c:4501)
                  >> ==22962==    by 0x8076FE0: eval4 (eval.c:4196)
                  >> ==22962==    by 0x8076E38: eval3 (eval.c:4108)
                  >> ==22962==    by 0x8076CC4: eval2 (eval.c:4037)
                  >> ==22962==    by 0x8076AF4: eval1 (eval.c:3962)
                  >> ==22962==    by 0x8076A5B: eval0 (eval.c:3919)
                  >> ==22962==    by 0x807326C: ex_let (eval.c:1833)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >> ==22962==    by 0x80A450B: do_cmdline (ex_docmd.c:1096)
                  >> ==22962==    by 0x8090507: call_user_func (eval.c:21381)
                  >> ==22962==    by 0x807C6DD: call_func (eval.c:8159)
                  >> ==22962==    by 0x807C321: get_func_tv (eval.c:8005)
                  >> ==22962==    by 0x8075C03: ex_call (eval.c:3341)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >> ==22962==
                  >> ==22962==
                  >> ==22962== 33,288 bytes in 5,548 blocks are possibly lost in loss
                  >> record 114 of 125
                  >> ==22962==    at 0x402603E: malloc (vg_replace_malloc.c:207)
                  >> ==22962==    by 0x81147FD: lalloc (misc2.c:866)
                  >> ==22962==    by 0x8114708: alloc (misc2.c:765)
                  >> ==22962==    by 0x8114C16: vim_strsave (misc2.c:1177)
                  >> ==22962==    by 0x808C427: copy_tv (eval.c:19380)
                  >> ==22962==    by 0x807B117: dict_copy (eval.c:6961)
                  >> ==22962==    by 0x808C662: item_copy (eval.c:19471)
                  >> ==22962==    by 0x807DB82: f_copy (eval.c:9141)
                  >> ==22962==    by 0x807C7DF: call_func (eval.c:8188)
                  >> ==22962==    by 0x807C321: get_func_tv (eval.c:8005)
                  >> ==22962==    by 0x807859A: eval7 (eval.c:5018)
                  >> ==22962==    by 0x8077EA3: eval6 (eval.c:4685)
                  >> ==22962==    by 0x8077A8F: eval5 (eval.c:4501)
                  >> ==22962==    by 0x8076FE0: eval4 (eval.c:4196)
                  >> ==22962==    by 0x8076E38: eval3 (eval.c:4108)
                  >> ==22962==    by 0x8076CC4: eval2 (eval.c:4037)
                  >> ==22962==    by 0x8076AF4: eval1 (eval.c:3962)
                  >> ==22962==    by 0x8076A5B: eval0 (eval.c:3919)
                  >> ==22962==    by 0x807326C: ex_let (eval.c:1833)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >> ==22962==    by 0x80A450B: do_cmdline (ex_docmd.c:1096)
                  >> ==22962==    by 0x8090507: call_user_func (eval.c:21381)
                  >> ==22962==    by 0x807C6DD: call_func (eval.c:8159)
                  >> ==22962==    by 0x807C321: get_func_tv (eval.c:8005)
                  >> ==22962==    by 0x8075C03: ex_call (eval.c:3341)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >> ==22962==    by 0x80A450B: do_cmdline (ex_docmd.c:1096)
                  >> ==22962==    by 0x80A2793: do_source (ex_cmds2.c:3119)
                  >> ==22962==    by 0x80A2047: cmd_source (ex_cmds2.c:2741)
                  >> ==22962==    by 0x80A1F9B: ex_source (ex_cmds2.c:2714)
                  >> ==22962==
                  >> ==22962==
                  >> ==22962== 49,932 bytes in 8,322 blocks are possibly lost in loss
                  >> record 115 of 125
                  >> ==22962==    at 0x402603E: malloc (vg_replace_malloc.c:207)
                  >> ==22962==    by 0x81147FD: lalloc (misc2.c:866)
                  >> ==22962==    by 0x8114708: alloc (misc2.c:765)
                  >> ==22962==    by 0x8114C16: vim_strsave (misc2.c:1177)
                  >> ==22962==    by 0x808C427: copy_tv (eval.c:19380)
                  >> ==22962==    by 0x807B117: dict_copy (eval.c:6961)
                  >> ==22962==    by 0x808C662: item_copy (eval.c:19471)
                  >> ==22962==    by 0x807DB82: f_copy (eval.c:9141)
                  >> ==22962==    by 0x807C7DF: call_func (eval.c:8188)
                  >> ==22962==    by 0x807C321: get_func_tv (eval.c:8005)
                  >> ==22962==    by 0x807859A: eval7 (eval.c:5018)
                  >> ==22962==    by 0x8077EA3: eval6 (eval.c:4685)
                  >> ==22962==    by 0x8077A8F: eval5 (eval.c:4501)
                  >> ==22962==    by 0x8076FE0: eval4 (eval.c:4196)
                  >> ==22962==    by 0x8076E38: eval3 (eval.c:4108)
                  >> ==22962==    by 0x8076CC4: eval2 (eval.c:4037)
                  >> ==22962==    by 0x8076AF4: eval1 (eval.c:3962)
                  >> ==22962==    by 0x8076A5B: eval0 (eval.c:3919)
                  >> ==22962==    by 0x807326C: ex_let (eval.c:1833)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >> ==22962==    by 0x80A450B: do_cmdline (ex_docmd.c:1096)
                  >> ==22962==    by 0x8090507: call_user_func (eval.c:21381)
                  >> ==22962==    by 0x807C6DD: call_func (eval.c:8159)
                  >> ==22962==    by 0x807C321: get_func_tv (eval.c:8005)
                  >> ==22962==    by 0x808AF05: handle_subscript (eval.c:18491)
                  >> ==22962==    by 0x8078640: eval7 (eval.c:5046)
                  >> ==22962==    by 0x8077EA3: eval6 (eval.c:4685)
                  >> ==22962==    by 0x8077A8F: eval5 (eval.c:4501)
                  >> ==22962==    by 0x8076FE0: eval4 (eval.c:4196)
                  >> ==22962==    by 0x8076E38: eval3 (eval.c:4108)
                  >> ==22962==
                  >> ==22962==
                  >> ==22962== 58,254 bytes in 2,774 blocks are possibly lost in loss
                  >> record 116 of 125
                  >> ==22962==    at 0x402603E: malloc (vg_replace_malloc.c:207)
                  >> ==22962==    by 0x81147FD: lalloc (misc2.c:866)
                  >> ==22962==    by 0x8114708: alloc (misc2.c:765)
                  >> ==22962==    by 0x807AEFC: dictitem_alloc (eval.c:6855)
                  >> ==22962==    by 0x807507D: set_var_lval (eval.c:2864)
                  >> ==22962==    by 0x8074374: ex_let_one (eval.c:2422)
                  >> ==22962==    by 0x807331F: ex_let_vars (eval.c:1877)
                  >> ==22962==    by 0x80732D0: ex_let (eval.c:1842)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >> ==22962==    by 0x80A450B: do_cmdline (ex_docmd.c:1096)
                  >> ==22962==    by 0x8090507: call_user_func (eval.c:21381)
                  >> ==22962==    by 0x807C6DD: call_func (eval.c:8159)
                  >> ==22962==    by 0x807C321: get_func_tv (eval.c:8005)
                  >> ==22962==    by 0x8075C03: ex_call (eval.c:3341)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >> ==22962==    by 0x80A450B: do_cmdline (ex_docmd.c:1096)
                  >> ==22962==    by 0x8090507: call_user_func (eval.c:21381)
                  >> ==22962==    by 0x807C6DD: call_func (eval.c:8159)
                  >> ==22962==    by 0x807C321: get_func_tv (eval.c:8005)
                  >> ==22962==    by 0x8075C03: ex_call (eval.c:3341)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >> ==22962==    by 0x80A450B: do_cmdline (ex_docmd.c:1096)
                  >> ==22962==    by 0x80A2793: do_source (ex_cmds2.c:3119)
                  >> ==22962==    by 0x80A2047: cmd_source (ex_cmds2.c:2741)
                  >> ==22962==    by 0x80A1F9B: ex_source (ex_cmds2.c:2714)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >> ==22962==    by 0x80A450B: do_cmdline (ex_docmd.c:1096)
                  >> ==22962==    by 0x812ACC4: nv_colon (normal.c:5227)
                  >> ==22962==    by 0x812430E: normal_cmd (normal.c:1189)
                  >> ==22962==    by 0x80E6F3D: main_loop (main.c:1180)
                  >> ==22962==
                  >> ==22962==
                  >> ==22962== 77,672 bytes in 2,774 blocks are possibly lost in loss
                  >> record 117 of 125
                  >> ==22962==    at 0x402603E: malloc (vg_replace_malloc.c:207)
                  >> ==22962==    by 0x81147FD: lalloc (misc2.c:866)
                  >> ==22962==    by 0x8114708: alloc (misc2.c:765)
                  >> ==22962==    by 0x807AEFC: dictitem_alloc (eval.c:6855)
                  >> ==22962==    by 0x807507D: set_var_lval (eval.c:2864)
                  >> ==22962==    by 0x8074374: ex_let_one (eval.c:2422)
                  >> ==22962==    by 0x807331F: ex_let_vars (eval.c:1877)
                  >> ==22962==    by 0x80732D0: ex_let (eval.c:1842)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >> ==22962==    by 0x80A450B: do_cmdline (ex_docmd.c:1096)
                  >> ==22962==    by 0x8090507: call_user_func (eval.c:21381)
                  >> ==22962==    by 0x807C6DD: call_func (eval.c:8159)
                  >> ==22962==    by 0x807C321: get_func_tv (eval.c:8005)
                  >> ==22962==    by 0x808AF05: handle_subscript (eval.c:18491)
                  >> ==22962==    by 0x8078640: eval7 (eval.c:5046)
                  >> ==22962==    by 0x8077EA3: eval6 (eval.c:4685)
                  >> ==22962==    by 0x8077A8F: eval5 (eval.c:4501)
                  >> ==22962==    by 0x8076FE0: eval4 (eval.c:4196)
                  >> ==22962==    by 0x8076E38: eval3 (eval.c:4108)
                  >> ==22962==    by 0x8076CC4: eval2 (eval.c:4037)
                  >> ==22962==    by 0x8076AF4: eval1 (eval.c:3962)
                  >> ==22962==    by 0x8076A5B: eval0 (eval.c:3919)
                  >> ==22962==    by 0x807326C: ex_let (eval.c:1833)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >> ==22962==    by 0x80A450B: do_cmdline (ex_docmd.c:1096)
                  >> ==22962==    by 0x8090507: call_user_func (eval.c:21381)
                  >> ==22962==    by 0x807C6DD: call_func (eval.c:8159)
                  >> ==22962==    by 0x807C321: get_func_tv (eval.c:8005)
                  >> ==22962==    by 0x8075C03: ex_call (eval.c:3341)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >> ==22962==
                  >> ==22962==
                  >> ==22962== 133,152 bytes in 5,548 blocks are possibly lost in loss
                  >> record 118 of 125
                  >> ==22962==    at 0x402603E: malloc (vg_replace_malloc.c:207)
                  >> ==22962==    by 0x81147FD: lalloc (misc2.c:866)
                  >> ==22962==    by 0x8114708: alloc (misc2.c:765)
                  >> ==22962==    by 0x807AEFC: dictitem_alloc (eval.c:6855)
                  >> ==22962==    by 0x807B0B3: dict_copy (eval.c:6948)
                  >> ==22962==    by 0x808C662: item_copy (eval.c:19471)
                  >> ==22962==    by 0x807DB82: f_copy (eval.c:9141)
                  >> ==22962==    by 0x807C7DF: call_func (eval.c:8188)
                  >> ==22962==    by 0x807C321: get_func_tv (eval.c:8005)
                  >> ==22962==    by 0x807859A: eval7 (eval.c:5018)
                  >> ==22962==    by 0x8077EA3: eval6 (eval.c:4685)
                  >> ==22962==    by 0x8077A8F: eval5 (eval.c:4501)
                  >> ==22962==    by 0x8076FE0: eval4 (eval.c:4196)
                  >> ==22962==    by 0x8076E38: eval3 (eval.c:4108)
                  >> ==22962==    by 0x8076CC4: eval2 (eval.c:4037)
                  >> ==22962==    by 0x8076AF4: eval1 (eval.c:3962)
                  >> ==22962==    by 0x8076A5B: eval0 (eval.c:3919)
                  >> ==22962==    by 0x807326C: ex_let (eval.c:1833)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >> ==22962==    by 0x80A450B: do_cmdline (ex_docmd.c:1096)
                  >> ==22962==    by 0x8090507: call_user_func (eval.c:21381)
                  >> ==22962==    by 0x807C6DD: call_func (eval.c:8159)
                  >> ==22962==    by 0x807C321: get_func_tv (eval.c:8005)
                  >> ==22962==    by 0x8075C03: ex_call (eval.c:3341)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >> ==22962==    by 0x80A450B: do_cmdline (ex_docmd.c:1096)
                  >> ==22962==    by 0x80A2793: do_source (ex_cmds2.c:3119)
                  >> ==22962==    by 0x80A2047: cmd_source (ex_cmds2.c:2741)
                  >> ==22962==    by 0x80A1F9B: ex_source (ex_cmds2.c:2714)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >> ==22962==
                  >> ==22962==
                  >> ==22962== 160,892 bytes in 5,548 blocks are possibly lost in loss
                  >> record 119 of 125
                  >> ==22962==    at 0x402603E: malloc (vg_replace_malloc.c:207)
                  >> ==22962==    by 0x81147FD: lalloc (misc2.c:866)
                  >> ==22962==    by 0x8114708: alloc (misc2.c:765)
                  >> ==22962==    by 0x807AEFC: dictitem_alloc (eval.c:6855)
                  >> ==22962==    by 0x807507D: set_var_lval (eval.c:2864)
                  >> ==22962==    by 0x8074374: ex_let_one (eval.c:2422)
                  >> ==22962==    by 0x807331F: ex_let_vars (eval.c:1877)
                  >> ==22962==    by 0x80732D0: ex_let (eval.c:1842)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >> ==22962==    by 0x80A450B: do_cmdline (ex_docmd.c:1096)
                  >> ==22962==    by 0x8090507: call_user_func (eval.c:21381)
                  >> ==22962==    by 0x807C6DD: call_func (eval.c:8159)
                  >> ==22962==    by 0x807C321: get_func_tv (eval.c:8005)
                  >> ==22962==    by 0x8075C03: ex_call (eval.c:3341)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >> ==22962==    by 0x80A450B: do_cmdline (ex_docmd.c:1096)
                  >> ==22962==    by 0x80A2793: do_source (ex_cmds2.c:3119)
                  >> ==22962==    by 0x80A2047: cmd_source (ex_cmds2.c:2741)
                  >> ==22962==    by 0x80A1F9B: ex_source (ex_cmds2.c:2714)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >> ==22962==    by 0x80A450B: do_cmdline (ex_docmd.c:1096)
                  >> ==22962==    by 0x812ACC4: nv_colon (normal.c:5227)
                  >> ==22962==    by 0x812430E: normal_cmd (normal.c:1189)
                  >> ==22962==    by 0x80E6F3D: main_loop (main.c:1180)
                  >> ==22962==    by 0x80E6A8A: main (main.c:939)
                  >> ==22962==
                  >> ==22962==
                  >> ==22962== 213,598 bytes in 8,322 blocks are possibly lost in loss
                  >> record 120 of 125
                  >> ==22962==    at 0x402603E: malloc (vg_replace_malloc.c:207)
                  >> ==22962==    by 0x81147FD: lalloc (misc2.c:866)
                  >> ==22962==    by 0x8114708: alloc (misc2.c:765)
                  >> ==22962==    by 0x807AEFC: dictitem_alloc (eval.c:6855)
                  >> ==22962==    by 0x807B0B3: dict_copy (eval.c:6948)
                  >> ==22962==    by 0x808C662: item_copy (eval.c:19471)
                  >> ==22962==    by 0x807DB82: f_copy (eval.c:9141)
                  >> ==22962==    by 0x807C7DF: call_func (eval.c:8188)
                  >> ==22962==    by 0x807C321: get_func_tv (eval.c:8005)
                  >> ==22962==    by 0x807859A: eval7 (eval.c:5018)
                  >> ==22962==    by 0x8077EA3: eval6 (eval.c:4685)
                  >> ==22962==    by 0x8077A8F: eval5 (eval.c:4501)
                  >> ==22962==    by 0x8076FE0: eval4 (eval.c:4196)
                  >> ==22962==    by 0x8076E38: eval3 (eval.c:4108)
                  >> ==22962==    by 0x8076CC4: eval2 (eval.c:4037)
                  >> ==22962==    by 0x8076AF4: eval1 (eval.c:3962)
                  >> ==22962==    by 0x8076A5B: eval0 (eval.c:3919)
                  >> ==22962==    by 0x807326C: ex_let (eval.c:1833)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >> ==22962==    by 0x80A450B: do_cmdline (ex_docmd.c:1096)
                  >> ==22962==    by 0x8090507: call_user_func (eval.c:21381)
                  >> ==22962==    by 0x807C6DD: call_func (eval.c:8159)
                  >> ==22962==    by 0x807C321: get_func_tv (eval.c:8005)
                  >> ==22962==    by 0x808AF05: handle_subscript (eval.c:18491)
                  >> ==22962==    by 0x8078640: eval7 (eval.c:5046)
                  >> ==22962==    by 0x8077EA3: eval6 (eval.c:4685)
                  >> ==22962==    by 0x8077A8F: eval5 (eval.c:4501)
                  >> ==22962==    by 0x8076FE0: eval4 (eval.c:4196)
                  >> ==22962==    by 0x8076E38: eval3 (eval.c:4108)
                  >> ==22962==    by 0x8076CC4: eval2 (eval.c:4037)
                  >> ==22962==
                  >> ==22962==
                  >> ==22962== 288,496 bytes in 5,548 blocks are possibly lost in loss
                  >> record 121 of 125
                  >> ==22962==    at 0x402603E: malloc (vg_replace_malloc.c:207)
                  >> ==22962==    by 0x81147FD: lalloc (misc2.c:866)
                  >> ==22962==    by 0x8114723: alloc_clear (misc2.c:777)
                  >> ==22962==    by 0x80797D0: list_alloc (eval.c:5729)
                  >> ==22962==    by 0x807961D: get_list_tv (eval.c:5667)
                  >> ==22962==    by 0x807837D: eval7 (eval.c:4943)
                  >> ==22962==    by 0x8077EA3: eval6 (eval.c:4685)
                  >> ==22962==    by 0x8077A8F: eval5 (eval.c:4501)
                  >> ==22962==    by 0x8076FE0: eval4 (eval.c:4196)
                  >> ==22962==    by 0x8076E38: eval3 (eval.c:4108)
                  >> ==22962==    by 0x8076CC4: eval2 (eval.c:4037)
                  >> ==22962==    by 0x8076AF4: eval1 (eval.c:3962)
                  >> ==22962==    by 0x8076A5B: eval0 (eval.c:3919)
                  >> ==22962==    by 0x807326C: ex_let (eval.c:1833)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >> ==22962==    by 0x80A450B: do_cmdline (ex_docmd.c:1096)
                  >> ==22962==    by 0x8090507: call_user_func (eval.c:21381)
                  >> ==22962==    by 0x807C6DD: call_func (eval.c:8159)
                  >> ==22962==    by 0x807C321: get_func_tv (eval.c:8005)
                  >> ==22962==    by 0x8075C03: ex_call (eval.c:3341)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >> ==22962==    by 0x80A450B: do_cmdline (ex_docmd.c:1096)
                  >> ==22962==    by 0x8090507: call_user_func (eval.c:21381)
                  >> ==22962==    by 0x807C6DD: call_func (eval.c:8159)
                  >> ==22962==    by 0x807C321: get_func_tv (eval.c:8005)
                  >> ==22962==    by 0x8075C03: ex_call (eval.c:3341)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >> ==22962==    by 0x80A450B: do_cmdline (ex_docmd.c:1096)
                  >> ==22962==    by 0x80A2793: do_source (ex_cmds2.c:3119)
                  >> ==22962==    by 0x80A2047: cmd_source (ex_cmds2.c:2741)
                  >> ==22962==
                  >> ==22962==
                  >> ==22962== 399,456 bytes in 16,644 blocks are possibly lost in loss
                  >> record 122 of 125
                  >> ==22962==    at 0x402603E: malloc (vg_replace_malloc.c:207)
                  >> ==22962==    by 0x81147FD: lalloc (misc2.c:866)
                  >> ==22962==    by 0x8114708: alloc (misc2.c:765)
                  >> ==22962==    by 0x807994D: listitem_alloc (eval.c:5810)
                  >> ==22962==    by 0x807967A: get_list_tv (eval.c:5679)
                  >> ==22962==    by 0x807837D: eval7 (eval.c:4943)
                  >> ==22962==    by 0x8077EA3: eval6 (eval.c:4685)
                  >> ==22962==    by 0x8077A8F: eval5 (eval.c:4501)
                  >> ==22962==    by 0x8076FE0: eval4 (eval.c:4196)
                  >> ==22962==    by 0x8076E38: eval3 (eval.c:4108)
                  >> ==22962==    by 0x8076CC4: eval2 (eval.c:4037)
                  >> ==22962==    by 0x8076AF4: eval1 (eval.c:3962)
                  >> ==22962==    by 0x8076A5B: eval0 (eval.c:3919)
                  >> ==22962==    by 0x807326C: ex_let (eval.c:1833)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >> ==22962==    by 0x80A450B: do_cmdline (ex_docmd.c:1096)
                  >> ==22962==    by 0x8090507: call_user_func (eval.c:21381)
                  >> ==22962==    by 0x807C6DD: call_func (eval.c:8159)
                  >> ==22962==    by 0x807C321: get_func_tv (eval.c:8005)
                  >> ==22962==    by 0x8075C03: ex_call (eval.c:3341)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >> ==22962==    by 0x80A450B: do_cmdline (ex_docmd.c:1096)
                  >> ==22962==    by 0x8090507: call_user_func (eval.c:21381)
                  >> ==22962==    by 0x807C6DD: call_func (eval.c:8159)
                  >> ==22962==    by 0x807C321: get_func_tv (eval.c:8005)
                  >> ==22962==    by 0x8075C03: ex_call (eval.c:3341)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >> ==22962==    by 0x80A450B: do_cmdline (ex_docmd.c:1096)
                  >> ==22962==    by 0x80A2793: do_source (ex_cmds2.c:3119)
                  >> ==22962==    by 0x80A2047: cmd_source (ex_cmds2.c:2741)
                  >> ==22962==
                  >> ==22962==
                  >> ==22962== 499,320 bytes in 2,774 blocks are possibly lost in loss
                  >> record 123 of 125
                  >> ==22962==    at 0x402603E: malloc (vg_replace_malloc.c:207)
                  >> ==22962==    by 0x81147FD: lalloc (misc2.c:866)
                  >> ==22962==    by 0x8114708: alloc (misc2.c:765)
                  >> ==22962==    by 0x807AD1E: dict_alloc (eval.c:6770)
                  >> ==22962==    by 0x807B6A8: get_dict_tv (eval.c:7216)
                  >> ==22962==    by 0x807839E: eval7 (eval.c:4949)
                  >> ==22962==    by 0x8077EA3: eval6 (eval.c:4685)
                  >> ==22962==    by 0x8077A8F: eval5 (eval.c:4501)
                  >> ==22962==    by 0x8076FE0: eval4 (eval.c:4196)
                  >> ==22962==    by 0x8076E38: eval3 (eval.c:4108)
                  >> ==22962==    by 0x8076CC4: eval2 (eval.c:4037)
                  >> ==22962==    by 0x8076AF4: eval1 (eval.c:3962)
                  >> ==22962==    by 0x8076A5B: eval0 (eval.c:3919)
                  >> ==22962==    by 0x807326C: ex_let (eval.c:1833)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >> ==22962==    by 0x80A450B: do_cmdline (ex_docmd.c:1096)
                  >> ==22962==    by 0x8090507: call_user_func (eval.c:21381)
                  >> ==22962==    by 0x807C6DD: call_func (eval.c:8159)
                  >> ==22962==    by 0x807C321: get_func_tv (eval.c:8005)
                  >> ==22962==    by 0x808AF05: handle_subscript (eval.c:18491)
                  >> ==22962==    by 0x8078640: eval7 (eval.c:5046)
                  >> ==22962==    by 0x8077EA3: eval6 (eval.c:4685)
                  >> ==22962==    by 0x8077A8F: eval5 (eval.c:4501)
                  >> ==22962==    by 0x8076FE0: eval4 (eval.c:4196)
                  >> ==22962==    by 0x8076E38: eval3 (eval.c:4108)
                  >> ==22962==    by 0x8076CC4: eval2 (eval.c:4037)
                  >> ==22962==    by 0x8076AF4: eval1 (eval.c:3962)
                  >> ==22962==    by 0x8076A5B: eval0 (eval.c:3919)
                  >> ==22962==    by 0x807326C: ex_let (eval.c:1833)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >> ==22962==
                  >> ==22962==
                  >> ==22962== 499,320 bytes in 2,774 blocks are possibly lost in loss
                  >> record 124 of 125
                  >> ==22962==    at 0x402603E: malloc (vg_replace_malloc.c:207)
                  >> ==22962==    by 0x81147FD: lalloc (misc2.c:866)
                  >> ==22962==    by 0x8114708: alloc (misc2.c:765)
                  >> ==22962==    by 0x807AD1E: dict_alloc (eval.c:6770)
                  >> ==22962==    by 0x807B040: dict_copy (eval.c:6933)
                  >> ==22962==    by 0x808C662: item_copy (eval.c:19471)
                  >> ==22962==    by 0x807DB82: f_copy (eval.c:9141)
                  >> ==22962==    by 0x807C7DF: call_func (eval.c:8188)
                  >> ==22962==    by 0x807C321: get_func_tv (eval.c:8005)
                  >> ==22962==    by 0x807859A: eval7 (eval.c:5018)
                  >> ==22962==    by 0x8077EA3: eval6 (eval.c:4685)
                  >> ==22962==    by 0x8077A8F: eval5 (eval.c:4501)
                  >> ==22962==    by 0x8076FE0: eval4 (eval.c:4196)
                  >> ==22962==    by 0x8076E38: eval3 (eval.c:4108)
                  >> ==22962==    by 0x8076CC4: eval2 (eval.c:4037)
                  >> ==22962==    by 0x8076AF4: eval1 (eval.c:3962)
                  >> ==22962==    by 0x8076A5B: eval0 (eval.c:3919)
                  >> ==22962==    by 0x807326C: ex_let (eval.c:1833)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >> ==22962==    by 0x80A450B: do_cmdline (ex_docmd.c:1096)
                  >> ==22962==    by 0x8090507: call_user_func (eval.c:21381)
                  >> ==22962==    by 0x807C6DD: call_func (eval.c:8159)
                  >> ==22962==    by 0x807C321: get_func_tv (eval.c:8005)
                  >> ==22962==    by 0x808AF05: handle_subscript (eval.c:18491)
                  >> ==22962==    by 0x8078640: eval7 (eval.c:5046)
                  >> ==22962==    by 0x8077EA3: eval6 (eval.c:4685)
                  >> ==22962==    by 0x8077A8F: eval5 (eval.c:4501)
                  >> ==22962==    by 0x8076FE0: eval4 (eval.c:4196)
                  >> ==22962==    by 0x8076E38: eval3 (eval.c:4108)
                  >> ==22962==    by 0x8076CC4: eval2 (eval.c:4037)
                  >> ==22962==
                  >> ==22962==
                  >> ==22962== 499,320 bytes in 2,774 blocks are possibly lost in loss
                  >> record 125 of 125
                  >> ==22962==    at 0x402603E: malloc (vg_replace_malloc.c:207)
                  >> ==22962==    by 0x81147FD: lalloc (misc2.c:866)
                  >> ==22962==    by 0x8114708: alloc (misc2.c:765)
                  >> ==22962==    by 0x807AD1E: dict_alloc (eval.c:6770)
                  >> ==22962==    by 0x807B040: dict_copy (eval.c:6933)
                  >> ==22962==    by 0x808C662: item_copy (eval.c:19471)
                  >> ==22962==    by 0x807DB82: f_copy (eval.c:9141)
                  >> ==22962==    by 0x807C7DF: call_func (eval.c:8188)
                  >> ==22962==    by 0x807C321: get_func_tv (eval.c:8005)
                  >> ==22962==    by 0x807859A: eval7 (eval.c:5018)
                  >> ==22962==    by 0x8077EA3: eval6 (eval.c:4685)
                  >> ==22962==    by 0x8077A8F: eval5 (eval.c:4501)
                  >> ==22962==    by 0x8076FE0: eval4 (eval.c:4196)
                  >> ==22962==    by 0x8076E38: eval3 (eval.c:4108)
                  >> ==22962==    by 0x8076CC4: eval2 (eval.c:4037)
                  >> ==22962==    by 0x8076AF4: eval1 (eval.c:3962)
                  >> ==22962==    by 0x8076A5B: eval0 (eval.c:3919)
                  >> ==22962==    by 0x807326C: ex_let (eval.c:1833)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >> ==22962==    by 0x80A450B: do_cmdline (ex_docmd.c:1096)
                  >> ==22962==    by 0x8090507: call_user_func (eval.c:21381)
                  >> ==22962==    by 0x807C6DD: call_func (eval.c:8159)
                  >> ==22962==    by 0x807C321: get_func_tv (eval.c:8005)
                  >> ==22962==    by 0x8075C03: ex_call (eval.c:3341)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >> ==22962==    by 0x80A450B: do_cmdline (ex_docmd.c:1096)
                  >> ==22962==    by 0x80A2793: do_source (ex_cmds2.c:3119)
                  >> ==22962==    by 0x80A2047: cmd_source (ex_cmds2.c:2741)
                  >> ==22962==    by 0x80A1F9B: ex_source (ex_cmds2.c:2714)
                  >> ==22962==    by 0x80A6C8B: do_one_cmd (ex_docmd.c:2622)
                  >
                  > Here is a new patch that hopefully fixes both the crash and the leaks.
                  > It's a bit tricky, but I think this catches all situations.
                  > Please verify.
                  >
                  > Note that with your script one needs to wait a few moments before
                  > exiting to give the garbage collector a chance.
                  >
                  >
                  > *** ../vim-7.2.185/src/eval.c   2009-05-16 17:29:37.000000000 +0200
                  > --- src/eval.c  2009-05-22 20:04:22.000000000 +0200
                  > ***************
                  > *** 129,136 ****
                  > --- 129,139 ----
                  >  /*
                  >   * When recursively copying lists and dicts we need to remember which ones we
                  >   * have done to avoid endless recursiveness.  This unique ID is used for that.
                  > +  * The last bit is used for previous_funccal, ignored when comparing.
                  >   */
                  >  static int current_copyID = 0;
                  > + #define COPYID_INC 2
                  > + #define COPYID_MASK (~0x1)
                  >
                  >  /*
                  >   * Array to hold the hashtab with variables local to each sourced script.
                  > ***************
                  > *** 439,444 ****
                  > --- 442,448 ----
                  >  static void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2));
                  >  static char_u *list2string __ARGS((typval_T *tv, int copyID));
                  >  static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo, int copyID));
                  > + static int free_unref_items __ARGS((int copyID));
                  >  static void set_ref_in_ht __ARGS((hashtab_T *ht, int copyID));
                  >  static void set_ref_in_list __ARGS((list_T *l, int copyID));
                  >  static void set_ref_in_item __ARGS((typval_T *tv, int copyID));
                  > ***************
                  > *** 6494,6507 ****
                  >      int
                  >  garbage_collect()
                  >  {
                  > !     dict_T    *dd;
                  > !     list_T    *ll;
                  > !     int               copyID = ++current_copyID;
                  >      buf_T     *buf;
                  >      win_T     *wp;
                  >      int               i;
                  >      funccall_T        *fc, **pfc;
                  > !     int               did_free = FALSE;
                  >  #ifdef FEAT_WINDOWS
                  >      tabpage_T *tp;
                  >  #endif
                  > --- 6498,6510 ----
                  >      int
                  >  garbage_collect()
                  >  {
                  > !     int               copyID;
                  >      buf_T     *buf;
                  >      win_T     *wp;
                  >      int               i;
                  >      funccall_T        *fc, **pfc;
                  > !     int               did_free;
                  > !     int               did_free_funccal = FALSE;
                  >  #ifdef FEAT_WINDOWS
                  >      tabpage_T *tp;
                  >  #endif
                  > ***************
                  > *** 6511,6520 ****
                  > --- 6514,6538 ----
                  >      may_garbage_collect = FALSE;
                  >      garbage_collect_at_exit = FALSE;
                  >
                  > +     /* We advance by two because we add one for items referenced through
                  > +      * previous_funccal. */
                  > +     current_copyID += COPYID_INC;
                  > +     copyID = current_copyID;
                  > +
                  >      /*
                  >       * 1. Go through all accessible variables and mark all lists and dicts
                  >       *    with copyID.
                  >       */
                  > +
                  > +     /* Don't free variables in the previous_funccal list unless they are only
                  > +      * referenced through previous_funccal.  This must be first, because if
                  > +      * the item is referenced elsewhere it must not be freed. */
                  > +     for (fc = previous_funccal; fc != NULL; fc = fc->caller)
                  > +     {
                  > +       set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID + 1);
                  > +       set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID + 1);
                  > +     }
                  > +
                  >      /* script-local variables */
                  >      for (i = 1; i <= ga_scripts.ga_len; ++i)
                  >        set_ref_in_ht(&SCRIPT_VARS(i), copyID);
                  > ***************
                  > *** 6546,6556 ****
                  >      /* v: vars */
                  >      set_ref_in_ht(&vimvarht, copyID);
                  >
                  >      /*
                  > !      * 2. Go through the list of dicts and free items without the copyID.
                  >       */
                  >      for (dd = first_dict; dd != NULL; )
                  > !       if (dd->dv_copyID != copyID)
                  >        {
                  >            /* Free the Dictionary and ordinary items it contains, but don't
                  >             * recurse into Lists and Dictionaries, they will be in the list
                  > --- 6564,6610 ----
                  >      /* v: vars */
                  >      set_ref_in_ht(&vimvarht, copyID);
                  >
                  > +     /* Free lists and dictionaries that are not referenced. */
                  > +     did_free = free_unref_items(copyID);
                  > +
                  > +     /* 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;
                  > +           did_free_funccal = TRUE;
                  > +       }
                  > +       else
                  > +           pfc = &(*pfc)->caller;
                  > +     }
                  > +     if (did_free_funccal)
                  > +       /* When a funccal was freed some more items might be garbage
                  > +        * collected, so run again. */
                  > +       (void)garbage_collect();
                  > +
                  > +     return did_free;
                  > + }
                  > +
                  > + /*
                  > +  * Free lists and dictionaries that are no longer referenced.
                  > +  */
                  > +     static int
                  > + free_unref_items(copyID)
                  > +     int copyID;
                  > + {
                  > +     dict_T    *dd;
                  > +     list_T    *ll;
                  > +     int               did_free = FALSE;
                  > +
                  >      /*
                  > !      * Go through the list of dicts and free items without the copyID.
                  >       */
                  >      for (dd = first_dict; dd != NULL; )
                  > !       if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK))
                  >        {
                  >            /* Free the Dictionary and ordinary items it contains, but don't
                  >             * recurse into Lists and Dictionaries, they will be in the list
                  > ***************
                  > *** 6565,6576 ****
                  >            dd = dd->dv_used_next;
                  >
                  >      /*
                  > !      * 3. Go through the list of lists and free items without the copyID.
                  > !      *    But don't free a list that has a watcher (used in a for loop), these
                  > !      *    are not referenced anywhere.
                  >       */
                  >      for (ll = first_list; ll != NULL; )
                  > !       if (ll->lv_copyID != copyID && ll->lv_watch == NULL)
                  >        {
                  >            /* Free the List and ordinary items it contains, but don't recurse
                  >             * into Lists and Dictionaries, they will be in the list of dicts
                  > --- 6619,6631 ----
                  >            dd = dd->dv_used_next;
                  >
                  >      /*
                  > !      * Go through the list of lists and free items without the copyID.
                  > !      * But don't free a list that has a watcher (used in a for loop), these
                  > !      * are not referenced anywhere.
                  >       */
                  >      for (ll = first_list; ll != NULL; )
                  > !       if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)
                  > !                                                     && ll->lv_watch == NULL)
                  >        {
                  >            /* Free the List and ordinary items it contains, but don't recurse
                  >             * into Lists and Dictionaries, they will be in the list of dicts
                  > ***************
                  > *** 6584,6603 ****
                  >        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;
                  >  }
                  >
                  > --- 6639,6644 ----
                  > ***************
                  > *** 18842,18847 ****
                  > --- 18883,18889 ----
                  >  {
                  >      hash_init(&dict->dv_hashtab);
                  >      dict->dv_refcount = DO_NOT_FREE_CNT;
                  > +     dict->dv_copyID = 0;
                  >      dict_var->di_tv.vval.v_dict = dict;
                  >      dict_var->di_tv.v_type = VAR_DICT;
                  >      dict_var->di_tv.v_lock = VAR_FIXED;
                  > ***************
                  > *** 21294,21301 ****
                  >      current_funccal = fc->caller;
                  >      --depth;
                  >
                  > !     /* if the a:000 list and the a: dict are not referenced we can free the
                  > !      * funccall_T and what's in it. */
                  >      if (fc->l_varlist.lv_refcount == DO_NOT_FREE_CNT
                  >            && fc->l_vars.dv_refcount == DO_NOT_FREE_CNT
                  >            && fc->l_avars.dv_refcount == DO_NOT_FREE_CNT)
                  > --- 21336,21343 ----
                  >      current_funccal = fc->caller;
                  >      --depth;
                  >
                  > !     /* If the a:000 list and the l: and a: dicts are not referenced we can
                  > !      * free the funccall_T and what's in it. */
                  >      if (fc->l_varlist.lv_refcount == DO_NOT_FREE_CNT
                  >            && fc->l_vars.dv_refcount == DO_NOT_FREE_CNT
                  >            && fc->l_avars.dv_refcount == DO_NOT_FREE_CNT)
                  > ***************
                  > *** 21334,21340 ****
                  >
                  >  /*
                  >   * Return TRUE if items in "fc" do not have "copyID".  That means they are not
                  > !  * referenced from anywhere.
                  >   */
                  >      static int
                  >  can_free_funccal(fc, copyID)
                  > --- 21376,21382 ----
                  >
                  >  /*
                  >   * Return TRUE if items in "fc" do not have "copyID".  That means they are not
                  > !  * referenced from anywhere that is in use.
                  >   */
                  >      static int
                  >  can_free_funccal(fc, copyID)
                  >
                  >
                  > --
                  > Why I like vim:
                  >> I like VIM because, when I ask a question in this newsgroup, I get a
                  >> one-line answer.  With xemacs, I get a 1Kb lisp script with bugs in it ;-)
                  >
                  >  /// Bram Moolenaar -- Bram@... -- 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    ///
                  >


                  With this patch applied MacVim still crashes for me. Note that it
                  doesn't do that if I instead apply the second Nico's patch. These are
                  details of from gdb:

                  Exception Type: EXC_BAD_ACCESS (SIGBUS)
                  Exception Codes: KERN_PROTECTION_FAILURE at 0x00000000000b7058
                  Crashed Thread: 0
                  (gdb) where
                  #0 0x0002afa1 in dict_free (d=0x35a42f0, recurse=1) at eval.c:6772
                  #1 0x0002b07a in dict_unref (d=0x35a42f0) at eval.c:6752
                  #2 0x0002a980 in clear_tv (varp=0x3413f60) at eval.c:18600
                  #3 0x0002c217 in vars_clear_ext (ht=0x8589c0, free_val=1) at eval.c:19037
                  #4 0x0002c25e in vars_clear (ht=0x34119f0) at eval.c:19009
                  #5 0x0002c285 in free_funccal (fc=0x858800, free_val=1) at eval.c:21512
                  #6 0x0002c6ee in garbage_collect () at eval.c:6579
                  #7 0x00075939 in before_blocking () at getchar.c:1473
                  #8 0x000dd53d in mch_inchar (buf=0x35a7001 "", maxlen=95, wtime=-1,
                  tb_change_cnt=21118) at os_unix.c:385
                  #9 0x00136ec5 in ui_inchar (buf=0x35a7001 "", maxlen=95, wtime=-1,
                  tb_change_cnt=21118) at ui.c:193
                  #10 0x00075c3a in inchar (buf=0x35a7001 "", maxlen=287, wait_time=-1,
                  tb_change_cnt=21118) at getchar.c:2959
                  #11 0x00078eda in vgetorpeek (advance=1) at getchar.c:2735
                  #12 0x00079441 in vgetc () at getchar.c:1552
                  #13 0x00079898 in safe_vgetc () at getchar.c:1757
                  #14 0x000c09ed in normal_cmd (oap=0xbffff350, toplevel=1) at normal.c:654
                  #15 0x00082d39 in main_loop (cmdwin=0, noexmode=0) at main.c:1255
                  #16 0x00086a87 in main (argc=54598128, argv=0x34119f0) at main.c:1002
                  (gdb) list
                  6767
                  6768 /* Remove the dict from the list of dicts for garbage collection. */
                  6769 if (d->dv_used_prev == NULL)
                  6770 first_dict = d->dv_used_next;
                  6771 else
                  6772 d->dv_used_prev->dv_used_next = d->dv_used_next;
                  6773 if (d->dv_used_next != NULL)
                  6774 d->dv_used_next->dv_used_prev = d->dv_used_prev;
                  6775
                  6776 /* Lock the hashtab, we don't want it to resize while
                  freeing items. */
                  (gdb) p *d
                  $44 = {
                  dv_refcount = -1073741822,
                  dv_hashtab = {
                  ht_mask = 3234897895,
                  ht_used = 11,
                  ht_filled = 18,
                  ht_locked = 1,
                  ht_error = 0,
                  ht_array = 0x85ee00,
                  ht_smallarray = {{
                  hi_hash = 1680060352,
                  hi_key = 0x34c692d "posStack"
                  }, {
                  hi_hash = 881893521,
                  hi_key = 0x347d13d "functionContainer"
                  }, {
                  hi_hash = 123778642,
                  hi_key = 0x342829d "wrap"
                  }, {
                  hi_hash = 1110333171,
                  hi_key = 0x3415ead "varPriority"
                  }, {
                  hi_hash = 122576644,
                  hi_key = 0x34bf01d "vars"
                  }, {
                  hi_hash = 2430892566,
                  hi_key = 0x34bde9d "wrapStartPos"
                  }, {
                  hi_hash = 1646883926,
                  hi_key = 0x34bd31d "tmplarr"
                  }, {
                  hi_hash = 2145903751,
                  hi_key = 0x34803ed "funcs"
                  }, {
                  hi_hash = 398141396,
                  hi_key = 0x34a1acd "lastPopup"
                  }, {
                  hi_hash = 2409478612,
                  hi_key = 0x34a295d "startColumn"
                  }, {
                  hi_hash = 3497526042,
                  hi_key = 0x341fc5d "stack"
                  }, {
                  hi_hash = 1528633632,
                  hi_key = 0x34a1c4d "wrappedNameTree"
                  }, {
                  hi_hash = 3594528268,
                  hi_key = 0x34bfb9d "tmpls"
                  }, {
                  hi_hash = 3360825129,
                  hi_key = 0x3487c5d "nameTree"
                  }, {
                  hi_hash = 0,
                  hi_key = 0x0
                  }, {
                  hi_hash = 2739356453,
                  hi_key = 0x3485b6d "keyword"
                  }}
                  },
                  dv_copyID = 1862,
                  dv_copydict = 0x3231203a,
                  dv_lock = 0 '\0',
                  dv_used_next = 0x34119f0,
                  dv_used_prev = 0xb6fb0
                  }

                  It looks like d->dv_refcount is invalid and d->dv_used_prev point is suspicious:

                  (gdb) p *d->dv_used_prev
                  $46 = {
                  dv_refcount = 533,
                  dv_hashtab = {
                  ht_mask = 552,
                  ht_used = 552,
                  ht_filled = 552,
                  ht_locked = 540,
                  ht_error = 547,
                  ht_array = 0x1f2,
                  ht_smallarray = {{
                  hi_hash = 96442,
                  hi_key = 0xba2feb00 <Address 0xba2feb00 out of bounds>
                  }, {
                  hi_hash = 8364,
                  hi_key = 0x60ba28eb <Address 0x60ba28eb out of bounds>
                  }, {
                  hi_hash = 3942645761,
                  hi_key = 0x161ba21 ""
                  }, {
                  hi_hash = 451608576,
                  hi_key = 0x17dba "\v#####"
                  }, {
                  hi_hash = 3121867520,
                  hi_key = 0x17e <Address 0x17e out of bounds>
                  }, {
                  hi_hash = 1387924715,
                  hi_key = 0xeb000001 <Address 0xeb000001 out of bounds>
                  }, {
                  hi_hash = 22264325,
                  hi_key = 0x4d8b0000 <Address 0x4d8b0000 out of bounds>
                  }, {
                  hi_hash = 608995784,
                  hi_key = 0x24148904 <Address 0x24148904 out of bounds>
                  }, {
                  hi_hash = 4293319400,
                  hi_key = 0xc84501ff <Address 0xc84501ff out of bounds>
                  }, {
                  hi_hash = 1003505151,
                  hi_key = 0x850fd075 <Address 0x850fd075 out of bounds>
                  }, {
                  hi_hash = 4294967067,
                  hi_key = 0xc6c87d8b <Address 0xc6c87d8b out of bounds>
                  }, {
                  hi_hash = 2105737223,
                  hi_key = 0x840f0010 <Address 0x840f0010 out of bounds>
                  }, {
                  hi_hash = 1409,
                  hi_key = 0x452bf889 <Address 0x452bf889 out of bounds>
                  }, {
                  hi_hash = 274041760,
                  hi_key = 0x72e90289 <Address 0x72e90289 out of bounds>
                  }, {
                  hi_hash = 2332033029,
                  hi_key = 0x1189144d <Address 0x1189144d out of bounds>
                  }, {
                  hi_hash = 2311355787,
                  hi_key = 0x2ce9ac7d <Address 0x2ce9ac7d out of bounds>
                  }}
                  },
                  dv_copyID = -1929379838,
                  dv_copydict = 0x4890146,
                  dv_lock = 36 '$',
                  dv_used_next = 0x4589ffff,
                  dv_used_prev = 0xfc085a0
                  }

                  I assume this is duble dealloc problem, but unfortunately I have no
                  idea how to track it down.
                  Hope it helps.

                  Kent

                  --~--~---------~--~----~------------~-------~--~----~
                  You received this message from the "vim_dev" maillist.
                  For more information, visit http://www.vim.org/maillist.php
                  -~----------~----~----~----~------~----~------~--~---
                • Bram Moolenaar
                  ... Do you have a reasonable simple way to reproduce this? -- Managers are like cats in a litter box. They instinctively shuffle things around to conceal what
                  Message 8 of 12 , May 27, 2009
                    Kent Sibilev wrote:

                    > With this patch applied MacVim still crashes for me. Note that it
                    > doesn't do that if I instead apply the second Nico's patch. These are
                    > details of from gdb:
                    >
                    > Exception Type: EXC_BAD_ACCESS (SIGBUS)
                    > Exception Codes: KERN_PROTECTION_FAILURE at 0x00000000000b7058
                    > Crashed Thread: 0
                    > (gdb) where
                    > #0 0x0002afa1 in dict_free (d=0x35a42f0, recurse=1) at eval.c:6772
                    > #1 0x0002b07a in dict_unref (d=0x35a42f0) at eval.c:6752
                    > #2 0x0002a980 in clear_tv (varp=0x3413f60) at eval.c:18600
                    > #3 0x0002c217 in vars_clear_ext (ht=0x8589c0, free_val=1) at eval.c:19037
                    > #4 0x0002c25e in vars_clear (ht=0x34119f0) at eval.c:19009
                    > #5 0x0002c285 in free_funccal (fc=0x858800, free_val=1) at eval.c:21512
                    > #6 0x0002c6ee in garbage_collect () at eval.c:6579
                    > #7 0x00075939 in before_blocking () at getchar.c:1473
                    > #8 0x000dd53d in mch_inchar (buf=0x35a7001 "", maxlen=95, wtime=-1,
                    > tb_change_cnt=21118) at os_unix.c:385
                    > #9 0x00136ec5 in ui_inchar (buf=0x35a7001 "", maxlen=95, wtime=-1,
                    > tb_change_cnt=21118) at ui.c:193
                    > #10 0x00075c3a in inchar (buf=0x35a7001 "", maxlen=287, wait_time=-1,
                    > tb_change_cnt=21118) at getchar.c:2959
                    > #11 0x00078eda in vgetorpeek (advance=1) at getchar.c:2735
                    > #12 0x00079441 in vgetc () at getchar.c:1552
                    > #13 0x00079898 in safe_vgetc () at getchar.c:1757
                    > #14 0x000c09ed in normal_cmd (oap=0xbffff350, toplevel=1) at normal.c:654
                    > #15 0x00082d39 in main_loop (cmdwin=0, noexmode=0) at main.c:1255
                    > #16 0x00086a87 in main (argc=54598128, argv=0x34119f0) at main.c:1002
                    > (gdb) list
                    > 6767
                    > 6768 /* Remove the dict from the list of dicts for garbage collection. */
                    > 6769 if (d->dv_used_prev == NULL)
                    > 6770 first_dict = d->dv_used_next;
                    > 6771 else
                    > 6772 d->dv_used_prev->dv_used_next = d->dv_used_next;
                    > 6773 if (d->dv_used_next != NULL)
                    > 6774 d->dv_used_next->dv_used_prev = d->dv_used_prev;
                    > 6775
                    > 6776 /* Lock the hashtab, we don't want it to resize while
                    > freeing items. */
                    > (gdb) p *d
                    > $44 = {
                    > dv_refcount = -1073741822,
                    > dv_hashtab = {
                    > ht_mask = 3234897895,
                    > ht_used = 11,
                    > ht_filled = 18,
                    > ht_locked = 1,
                    > ht_error = 0,
                    > ht_array = 0x85ee00,
                    > ht_smallarray = {{
                    > hi_hash = 1680060352,
                    > hi_key = 0x34c692d "posStack"
                    > }, {
                    > hi_hash = 881893521,
                    > hi_key = 0x347d13d "functionContainer"
                    > }, {
                    > hi_hash = 123778642,
                    > hi_key = 0x342829d "wrap"
                    > }, {
                    > hi_hash = 1110333171,
                    > hi_key = 0x3415ead "varPriority"
                    > }, {
                    > hi_hash = 122576644,
                    > hi_key = 0x34bf01d "vars"
                    > }, {
                    > hi_hash = 2430892566,
                    > hi_key = 0x34bde9d "wrapStartPos"
                    > }, {
                    > hi_hash = 1646883926,
                    > hi_key = 0x34bd31d "tmplarr"
                    > }, {
                    > hi_hash = 2145903751,
                    > hi_key = 0x34803ed "funcs"
                    > }, {
                    > hi_hash = 398141396,
                    > hi_key = 0x34a1acd "lastPopup"
                    > }, {
                    > hi_hash = 2409478612,
                    > hi_key = 0x34a295d "startColumn"
                    > }, {
                    > hi_hash = 3497526042,
                    > hi_key = 0x341fc5d "stack"
                    > }, {
                    > hi_hash = 1528633632,
                    > hi_key = 0x34a1c4d "wrappedNameTree"
                    > }, {
                    > hi_hash = 3594528268,
                    > hi_key = 0x34bfb9d "tmpls"
                    > }, {
                    > hi_hash = 3360825129,
                    > hi_key = 0x3487c5d "nameTree"
                    > }, {
                    > hi_hash = 0,
                    > hi_key = 0x0
                    > }, {
                    > hi_hash = 2739356453,
                    > hi_key = 0x3485b6d "keyword"
                    > }}
                    > },
                    > dv_copyID = 1862,
                    > dv_copydict = 0x3231203a,
                    > dv_lock = 0 '\0',
                    > dv_used_next = 0x34119f0,
                    > dv_used_prev = 0xb6fb0
                    > }
                    >
                    > It looks like d->dv_refcount is invalid and d->dv_used_prev point is suspicious:
                    >
                    > (gdb) p *d->dv_used_prev
                    > $46 = {
                    > dv_refcount = 533,
                    > dv_hashtab = {
                    > ht_mask = 552,
                    > ht_used = 552,
                    > ht_filled = 552,
                    > ht_locked = 540,
                    > ht_error = 547,
                    > ht_array = 0x1f2,
                    > ht_smallarray = {{
                    > hi_hash = 96442,
                    > hi_key = 0xba2feb00 <Address 0xba2feb00 out of bounds>
                    > }, {
                    > hi_hash = 8364,
                    > hi_key = 0x60ba28eb <Address 0x60ba28eb out of bounds>
                    > }, {
                    > hi_hash = 3942645761,
                    > hi_key = 0x161ba21 ""
                    > }, {
                    > hi_hash = 451608576,
                    > hi_key = 0x17dba "\v#####"
                    > }, {
                    > hi_hash = 3121867520,
                    > hi_key = 0x17e <Address 0x17e out of bounds>
                    > }, {
                    > hi_hash = 1387924715,
                    > hi_key = 0xeb000001 <Address 0xeb000001 out of bounds>
                    > }, {
                    > hi_hash = 22264325,
                    > hi_key = 0x4d8b0000 <Address 0x4d8b0000 out of bounds>
                    > }, {
                    > hi_hash = 608995784,
                    > hi_key = 0x24148904 <Address 0x24148904 out of bounds>
                    > }, {
                    > hi_hash = 4293319400,
                    > hi_key = 0xc84501ff <Address 0xc84501ff out of bounds>
                    > }, {
                    > hi_hash = 1003505151,
                    > hi_key = 0x850fd075 <Address 0x850fd075 out of bounds>
                    > }, {
                    > hi_hash = 4294967067,
                    > hi_key = 0xc6c87d8b <Address 0xc6c87d8b out of bounds>
                    > }, {
                    > hi_hash = 2105737223,
                    > hi_key = 0x840f0010 <Address 0x840f0010 out of bounds>
                    > }, {
                    > hi_hash = 1409,
                    > hi_key = 0x452bf889 <Address 0x452bf889 out of bounds>
                    > }, {
                    > hi_hash = 274041760,
                    > hi_key = 0x72e90289 <Address 0x72e90289 out of bounds>
                    > }, {
                    > hi_hash = 2332033029,
                    > hi_key = 0x1189144d <Address 0x1189144d out of bounds>
                    > }, {
                    > hi_hash = 2311355787,
                    > hi_key = 0x2ce9ac7d <Address 0x2ce9ac7d out of bounds>
                    > }}
                    > },
                    > dv_copyID = -1929379838,
                    > dv_copydict = 0x4890146,
                    > dv_lock = 36 '$',
                    > dv_used_next = 0x4589ffff,
                    > dv_used_prev = 0xfc085a0
                    > }
                    >
                    > I assume this is duble dealloc problem, but unfortunately I have no
                    > idea how to track it down.
                    > Hope it helps.

                    Do you have a reasonable simple way to reproduce this?

                    --
                    Managers are like cats in a litter box. They instinctively shuffle things
                    around to conceal what they've done.
                    (Scott Adams - The Dilbert principle)

                    /// Bram Moolenaar -- Bram@... -- 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
                    -~----------~----~----~----~------~----~------~--~---
                  Your message has been successfully submitted and would be delivered to recipients shortly.