While testing Vim with Valgrind memory checker,
I encountered this memory leak:

==6498== 183 bytes in 4 blocks are definitely lost in loss record 31 of 43
==6498==    at 0x4022765: malloc (vg_replace_malloc.c:149)
==6498==    by 0x8113B58: lalloc (misc2.c:862)
==6498==    by 0x8093F03: make_filter_cmd (ex_cmds.c:1528)
==6498==    by 0x809382E: do_filter (ex_cmds.c:1163)
==6498==    by 0x809357D: do_bang (ex_cmds.c:1031)
==6498==    by 0x80AE8F5: ex_bang (ex_docmd.c:8335)
==6498==    by 0x80A5BDE: do_one_cmd (ex_docmd.c:2623)
==6498==    by 0x80A342A: do_cmdline (ex_docmd.c:1099)
==6498==    by 0x80A2956: do_exmode (ex_docmd.c:656)
==6498==    by 0x8129EAB: nv_exmode (normal.c:5137)
==6498==    by 0x8123542: normal_cmd (normal.c:1152)
==6498==    by 0x80E6371: main_loop (main.c:1181)
==6498==    by 0x80E5EC1: main (main.c:940)

Unfortunately, I'm not sure how to reproduce it.  But looking
at the code, it is clear that there is one path where memory
is not freed.

In ex_cmds.c below, local variable cmd_buf is allocated
at line 1163,  then freed later at line 1202.   But in between,
line 1183 may do "goto error;" which will cause to return
without freeing local variable cmd_buf.

(ex_cmds.c)
1163     cmd_buf = make_filter_cmd(cmd, itmp, otmp);  <--------
cmd_buf is allocated here
1164     if (cmd_buf == NULL)
1165         goto filterend;
1166
1167     windgoto((int)Rows - 1, 0);
1168     cursor_on();
1169
1170     /*
1171      * When not redirecting the output the command can write
anything to the
1172      * screen. If 'shellredir' is equal to ">", screen may be messed up by
1173      * stderr output of external command. Clear the screen later.
1174      * If do_in is FALSE, this could be something like ":r !cat", which may
1175      * also mess up the screen, clear it later.
1176      */
1177     if (!do_out || STRCMP(p_srr, ">") == 0 || !do_in)
1178         redraw_later_clear();
1179
1180     if (do_out)
1181     {
1182         if (u_save((linenr_T)(line2), (linenr_T)(line2 + 1)) == FAIL)
1183             goto error;   <----------------  LEAK!!!
**************************
1184         redraw_curbuf_later(VALID);
1185     }
1186     read_linecount = curbuf->b_ml.ml_line_count;
1187
1188     /*
1189      * When call_shell() fails wait_return() is called to give the user a
1190      * chance to read the error messages. Otherwise errors are
ignored, so you
1191      * can see the error messages from the command that appear on
stdout; use
1192      * 'u' to fix the text
1193      * Switch to cooked mode when not redirecting stdin, avoids
that something
1194      * like ":r !cat" hangs.
1195      * Pass on the SHELL_DOOUT flag when the output is being redirected.
1196      */
1197     if (call_shell(cmd_buf, SHELL_FILTER | SHELL_COOKED | shell_flags))
1198     {
1199         redraw_later_clear();
1200         wait_return(FALSE);
1201     }
1202     vim_free(cmd_buf);  <------------ cmd_buf is freed here


I attach a patch which fixes it.

I'm using vim-7.1.291 on Linux x86.

-- Dominique

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

Index: ex_cmds.c
===================================================================
RCS file: /cvsroot/vim/vim7/src/ex_cmds.c,v
retrieving revision 1.107
diff -c -r1.107 ex_cmds.c
*** ex_cmds.c	18 Feb 2008 18:42:52 -0000	1.107
--- ex_cmds.c	5 Apr 2008 13:49:26 -0000
***************
*** 1180,1186 ****
--- 1180,1189 ----
      if (do_out)
      {
  	if (u_save((linenr_T)(line2), (linenr_T)(line2 + 1)) == FAIL)
+ 	{
+ 	    vim_free(cmd_buf);
  	    goto error;
+ 	}
  	redraw_curbuf_later(VALID);
      }
      read_linecount = curbuf->b_ml.ml_line_count;
***************
*** 4471,4477 ****
  	    /*
  	     * The new text is build up step by step, to avoid too much
  	     * copying.  There are these pieces:
! 	     * sub_firstline	The old text, unmodifed.
  	     * copycol		Column in the old text where we started
  	     *			looking for a match; from here old text still
  	     *			needs to be copied to the new text.
--- 4474,4480 ----
  	    /*
  	     * The new text is build up step by step, to avoid too much
  	     * copying.  There are these pieces:
! 	     * sub_firstline	The old text, unmodified.
  	     * copycol		Column in the old text where we started
  	     *			looking for a match; from here old text still
  	     *			needs to be copied to the new text.

Raspunde prin e-mail lui