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

Re: Fix for crash in eval.c

Expand Messages
  • Dominique Pellé
    ... Thanks. I can confirm that Valgrind detects the same errors on Linux x86 too using Vim-7.2.166. I did not try it earlier because I don t follow the
    Message 1 of 12 , May 3, 2009
    View Source
    • 0 Attachment
      Nico Weber wrote:

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

      ...snip...

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


      Thanks. I can confirm that Valgrind detects the same errors
      on Linux x86 too using Vim-7.2.166. I did not try it earlier
      because I don't follow the mailing list vim_mac.

      So bug is not mac specific, even though it does not cause
      a crash on Linux.

      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.

      Regards
      -- Dominique

      --~--~---------~--~----~------------~-------~--~----~
      You received this message from the "vim_dev" maillist.
      For more information, visit http://www.vim.org/maillist.php
      -~----------~----~----~----~------~----~------~--~---
    • Kana Natsuno
      ... Thank you for the patch! I encountered the same problem on Mac OS X and GNU/Linux since 7.2.70, but I couldn t reproduce the problem, so that I couldn t
      Message 2 of 12 , May 3, 2009
      View Source
      • 0 Attachment
        On Sun, 03 May 2009 08:06:13 +0900, Nico Weber <nicolasweber@...> 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
        > :

        Thank you for the patch!
        I encountered the same problem on Mac OS X and GNU/Linux since 7.2.70,
        but I couldn't reproduce the problem, so that I couldn't send a report on it.
        Now I should subscribe also vim_mac.


        --
        To Vim, or not to Vim.
        http://whileimautomaton.net/

        --~--~---------~--~----~------------~-------~--~----~
        You received this message from the "vim_dev" maillist.
        For more information, visit http://www.vim.org/maillist.php
        -~----------~----~----~----~------~----~------~--~---
      • Nico Weber
        Hi, ... 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
        Message 3 of 12 , May 3, 2009
        View Source
        • 0 Attachment
          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


          --~--~---------~--~----~------------~-------~--~----~
          You received this message from the "vim_dev" maillist.
          For more information, visit http://www.vim.org/maillist.php
          -~----------~----~----~----~------~----~------~--~---
        • 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 4 of 12 , May 3, 2009
          View Source
          • 0 Attachment
            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 5 of 12 , May 5, 2009
            View Source
            • 0 Attachment
              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 6 of 12 , May 5, 2009
              View Source
              • 0 Attachment
                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 7 of 12 , May 22, 2009
                View Source
                • 0 Attachment
                  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 8 of 12 , May 23, 2009
                  View Source
                  • 0 Attachment
                    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 9 of 12 , May 24, 2009
                    View Source
                    • 0 Attachment
                      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 10 of 12 , May 27, 2009
                      View Source
                      • 0 Attachment
                        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 11 of 12 , May 27, 2009
                        View Source
                        • 0 Attachment
                          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.