Hi

I can reproduce a memory leak 100% of the time in vim-7.1.123:

Start vim with:

  vim -u NONE -U NONE

Then set the following options:

  :set nocompatible
  :set wildmode=longest,list
  :set wildmenu

vim will then leak memory whenever file completion on Ex command
results in no match:

  :e /<TAB>     # OK no leak (file completion lists some files
                # /usr, /tmp, /dev, etc)

  :e /fff<TAB>  # leaks 1 block of memory! (assuming no filename start
                # with /fff)

Here is stack of the leak reported by valgrind (when exiting vim):

==12117== 21 bytes in 4 blocks are definitely lost in loss record 2 of 15
==12117==    at 0x4021620: malloc (vg_replace_malloc.c:149)
==12117==    by 0x8102F1C: lalloc (misc2.c:857)
==12117==    by 0x8102E3E: alloc (misc2.c:756)
==12117==    by 0x81032C9: vim_strnsave (misc2.c:1155)
==12117==    by 0x80B00F9: nextwild (ex_getln.c:3254)
==12117==    by 0x80AC44B: getcmdline (ex_getln.c:793)
==12117==    by 0x80AE69B: getexline (ex_getln.c:2078)
==12117==    by 0x8098E80: do_cmdline (ex_docmd.c:995)
==12117==    by 0x8116F0F: nv_colon (normal.c:5168)
==12117==    by 0x8111043: normal_cmd (normal.c:1141)
==12117==    by 0x80D7D22: main_loop (main.c:1181)
==12117==    by 0x80D7936: main (main.c:940)

Here is the relevant code where memory is allocated:

ex_getln.c:

3254     p2 = ExpandOne(xp, p1, vim_strnsave(&ccline.cmdbuff[i], oldlen),
3255             WILD_HOME_REPLACE|WILD_ADD_SLASH|WILD_SILENT|WILD_ESCAPE
3256                                                     |options, type);

Function vim_strnsave() allocates a block of memory and passes
it to function ExpanOne (3rd argument).

Adding some printf(), I can see that function ExpandOne()
returns without freeing its 3rd argument at line 3414:

misc2.c:

3413     if (mode == WILD_FREE)      /* only release file name */
3414         return NULL;

I think function ExpandOne() should free its 3rd argument
before returning at line 3414.

There are also 3 other lines in ExpandOne() where it can potentially
return without freeing its 3rd argument at lines 3396, 3397 and 3400
(though I am not sure whether they can happen in practice).  I did
not fix them but they could possibly be other leaks.

I attach a patch which fixes the leak at line 3414 which I can
reproduce as explained above.

Note that it's OK to have one block reported as leak (which is
actually not a leak because there is a static var orig_save
to cache I think) but it's not OK to leak more than one block.

I'm using vim-7.1 (patches 1-123), on Linux, built with
'configure --with-features=huge'

I built vim by uncommenting out "PROFILE_CFLAGS = -DEXITFREE"
in vim7/src/Makefile to help find leaks.  After uncommenting that line,
I had a compilation error (clip_exclude_prog() not declared):

gcc -c -I. -Iproto -DHAVE_CONFIG_H     -g -O0 -Wall
-Wmissing-prototypes -DEXITFREE        -o objects/misc2.o misc2.c
misc2.c: In function 'free_all_mem':
misc2.c:1040: error: 'clip_exclude_prog' undeclared (first use in this function)
misc2.c:1040: error: (Each undeclared identifier is reported only once
misc2.c:1040: error: for each function it appears in.)

I worked around that error by moving clip_exclude_prog() declaration out
of #ifdef FEAT_CLIPBOARD ... #endif. Should that be fixed too or is
there a better way to define EXITFREE in the build?

/Dominique

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

Index: src/ex_getln.c
===================================================================
RCS file: /cvsroot/vim/vim7/src/ex_getln.c,v
retrieving revision 1.74
diff -c -r1.74 ex_getln.c
*** src/ex_getln.c	29 Sep 2007 12:16:30 -0000	1.74
--- src/ex_getln.c	30 Sep 2007 14:34:16 -0000
***************
*** 3411,3417 ****
--- 3411,3420 ----
      findex = 0;
  
      if (mode == WILD_FREE)	/* only release file name */
+     {
+ 	vim_free(orig);
  	return NULL;
+     }
  
      if (xp->xp_numfiles == -1)
      {

Raspunde prin e-mail lui