Attached patch fixes 2 bugs with signs and X11 GUIs:
- The X11 GUI should not allocate the bitmap before calling
XpmReadFileToImage() since XpmReadFileToImage() API
does the memory allocation. As a result, memory for bitmap
is allocated twice (leak) whenever defining a sign with
an xpm icon in the X11 GUIs (athena, neXtaw, motif).
The following script for example which redefines the
same sign multiple times leaks memory at every iteration
when using GUI X11 athena, neXtaw, motif:
:while 1
:sign define foo text=>> texthl=Search icon=foo.xpm
:endwhile
- The X11 GUI frees memory incorrectly for the icon using
XFree() and vim_free() instead of calling XDestroyImage().
Using XFree() and vim_free() may possibly do the same
thing as XDestroyImage() but at least not when Vim is
built with -DMEM_PROFILE in which case vim_free() frees
an invalid pointer.
The XPM documentation indicates that XDestroyImage() should
be used to free the bitmap allocated by XpmReadFileToImage().
See http://www.cs.ualberta.ca/doc/Software_manuals/xpm.ps
Patch also frees gui_argv which was never freed.
Cheers
-- Dominique
--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---
Index: gui_x11.c
===================================================================
RCS file: /cvsroot/vim/vim7/src/gui_x11.c,v
retrieving revision 1.20
diff -c -r1.20 gui_x11.c
*** gui_x11.c 12 Nov 2008 12:08:45 -0000 1.20
--- gui_x11.c 22 Feb 2009 09:04:30 -0000
***************
*** 1587,1592 ****
--- 1587,1594 ----
XtCloseDisplay(gui.dpy);
gui.dpy = NULL;
vimShell = (Widget)0;
+ vim_free(gui_argv);
+ gui_argv = NULL;
}
/*
***************
*** 1761,1766 ****
--- 1763,1770 ----
* says that this isn't needed when exiting, so just skip it. */
XtCloseDisplay(gui.dpy);
#endif
+ vim_free(gui_argv);
+ gui_argv = NULL;
}
/*
***************
*** 3439,3484 ****
char_u *signfile;
{
XpmAttributes attrs;
! XImage *sign;
int status;
/*
* Setup the color substitution table.
*/
- sign = NULL;
if (signfile[0] != NUL && signfile[0] != '-')
{
! sign = (XImage *)alloc(sizeof(XImage));
! if (sign != NULL)
{
! XpmColorSymbol color[5] =
! {
! {"none", NULL, 0},
! {"iconColor1", NULL, 0},
! {"bottomShadowColor", NULL, 0},
! {"topShadowColor", NULL, 0},
! {"selectColor", NULL, 0}
! };
! attrs.valuemask = XpmColorSymbols;
! attrs.numsymbols = 2;
! attrs.colorsymbols = color;
! attrs.colorsymbols[0].pixel = gui.back_pixel;
! attrs.colorsymbols[1].pixel = gui.norm_pixel;
! status = XpmReadFileToImage(gui.dpy, (char *)signfile,
! &sign, NULL, &attrs);
!
! if (status == 0)
! {
! /* Sign width is fixed at two columns now.
! if (sign->width > gui.sign_width)
! gui.sign_width = sign->width + 8; */
! }
! else
! {
! vim_free(sign);
! sign = NULL;
! EMSG(_(e_signdata));
! }
}
}
--- 3443,3480 ----
char_u *signfile;
{
XpmAttributes attrs;
! XImage *sign = NULL;
int status;
/*
* Setup the color substitution table.
*/
if (signfile[0] != NUL && signfile[0] != '-')
{
! XpmColorSymbol color[5] =
{
! {"none", NULL, 0},
! {"iconColor1", NULL, 0},
! {"bottomShadowColor", NULL, 0},
! {"topShadowColor", NULL, 0},
! {"selectColor", NULL, 0}
! };
! attrs.valuemask = XpmColorSymbols;
! attrs.numsymbols = 2;
! attrs.colorsymbols = color;
! attrs.colorsymbols[0].pixel = gui.back_pixel;
! attrs.colorsymbols[1].pixel = gui.norm_pixel;
! status = XpmReadFileToImage(gui.dpy, (char *)signfile,
! &sign, NULL, &attrs);
! if (status == 0)
! {
! /* Sign width is fixed at two columns now.
! if (sign->width > gui.sign_width)
! gui.sign_width = sign->width + 8; */
! }
! else
! {
! EMSG(_(e_signdata));
}
}
***************
*** 3489,3496 ****
gui_mch_destroy_sign(sign)
void *sign;
{
! XFree(((XImage *)sign)->data);
! vim_free(sign);
}
#endif
--- 3485,3491 ----
gui_mch_destroy_sign(sign)
void *sign;
{
! XDestroyImage((XImage*)sign);
}
#endif