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 -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\        download, build and distribute -- http://www.A-A-P.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

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

Raspunde prin e-mail lui