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

Fix for crash in eval.c

Expand Messages
  • Nico Weber
    Hi, Valgrind memory checker finds several errors in vim-7.2 (patches 1-148) with the reproduction steps described at
    Message 1 of 12 , May 2, 2009
    • 0 Attachment
      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)
      ==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.


      Nico


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