Hi

Valgrind memory checker detects the following memory leak in Vim-7.2.148:

==12545== 264 bytes in 4 blocks are definitely lost in loss record 20 of 41
==12545==    at 0x402603E: malloc (vg_replace_malloc.c:207)
==12545==    by 0x811440D: lalloc (misc2.c:866)
==12545==    by 0x8114318: alloc (misc2.c:765)
==12545==    by 0x80F68EF: recover_names (memline.c:1536)
==12545==    by 0x80F553E: ml_recover (memline.c:891)
==12545==    by 0x80AD962: ex_recover (ex_docmd.c:7074)
==12545==    by 0x80A6D4B: do_one_cmd (ex_docmd.c:2622)
==12545==    by 0x80A45CB: do_cmdline (ex_docmd.c:1096)
==12545==    by 0x812A88A: nv_colon (normal.c:5218)
==12545==    by 0x8123EEE: normal_cmd (normal.c:1189)
==12545==    by 0x80E6C89: main_loop (main.c:1180)
==12545==    by 0x80E67D6: main (main.c:939)

Bug can easily be reproduced as follows:

1/ Create an empty directory

   $ mkdir /tmp/empty_dir

2/ Then whenever the following Ex command is entered in Vim,
   a memory leak happens:

    :recover /tmp/empty_dir/

Memory is allocated in memline.c:1536

1532    if (swapname != NULL)
1533    {
1534        if (mch_stat((char *)swapname, &st) != -1)     /* It exists! */
1535        {
1536            files = (char_u **)alloc((unsigned)sizeof(char_u *));
1537            if (files != NULL)
1538            {
1539                files[0] = swapname;
1540                swapname = NULL;
1541                num_files = 1;
1542            }

num_files is set to 1 at line 1541.  Then files[0] is freed at
line 1557 (but files is not freed) and num_files is decremented
from 1 to 0:

1554             for (i = 0; i < num_files; ++i)
1555                 if (fullpathcmp(p, files[i], TRUE) & FPC_SAME)
1556                 {
1557                     vim_free(files[i]);
1558                     --num_files;

files is then no longer freed (leak) since lines that would free it
is is inside 'if (num_files > 0)':

1609         if (num_files > 0)
1610             FreeWild(num_files, files);

Attached patch fixes it.

Regards
-- Dominique

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

Index: memline.c
===================================================================
RCS file: /cvsroot/vim/vim7/src/memline.c,v
retrieving revision 1.41
diff -c -r1.41 memline.c
*** memline.c	13 Jul 2008 17:40:43 -0000	1.41
--- memline.c	17 Apr 2009 01:25:07 -0000
***************
*** 1555,1563 ****
  		if (fullpathcmp(p, files[i], TRUE) & FPC_SAME)
  		{
  		    vim_free(files[i]);
! 		    --num_files;
! 		    for ( ; i < num_files; ++i)
! 			files[i] = files[i + 1];
  		}
  	}
  	if (nr > 0)
--- 1555,1565 ----
  		if (fullpathcmp(p, files[i], TRUE) & FPC_SAME)
  		{
  		    vim_free(files[i]);
! 		    if (--num_files == 0)
! 			vim_free(files);
! 		    else
! 			for ( ; i < num_files; ++i)
! 			    files[i] = files[i + 1];
  		}
  	}
  	if (nr > 0)
***************
*** 3522,3528 ****
  	    if (errno == EINVAL || errno == ENOENT)
  	    {
  		/* Found non-symlink or not existing file, stop here.
! 		 * When at the first level use the unmodifed name, skip the
  		 * call to vim_FullName(). */
  		if (depth == 1)
  		    return FAIL;
--- 3524,3530 ----
  	    if (errno == EINVAL || errno == ENOENT)
  	    {
  		/* Found non-symlink or not existing file, stop here.
! 		 * When at the first level use the unmodified name, skip the
  		 * call to vim_FullName(). */
  		if (depth == 1)
  		    return FAIL;
***************
*** 4560,4566 ****
  			buf->b_ml.ml_chunksize + curix,
  			(buf->b_ml.ml_usedchunks - curix) *
  			sizeof(chunksize_T));
! 	    /* Compute length of first half of lines in the splitted chunk */
  	    size = 0;
  	    linecnt = 0;
  	    while (curline < buf->b_ml.ml_line_count
--- 4562,4568 ----
  			buf->b_ml.ml_chunksize + curix,
  			(buf->b_ml.ml_usedchunks - curix) *
  			sizeof(chunksize_T));
! 	    /* Compute length of first half of lines in the split chunk */
  	    size = 0;
  	    linecnt = 0;
  	    while (curline < buf->b_ml.ml_line_count

Reply via email to