After installing libxt-dev lesstif2 lesstif2-dev libxpm-dev libxpm4,
I built Vim-7.1.311 ('huge' with Lesstif GUI) and found a couple of
minor issues:

- compilation warnings in vim7/src/gui_motif.c
- crash when exiting Vim & gvim (only when built with -DEXITFREE)
- memory leak in xsmp_close()


1/ Compilation warnings in vim7/src/gui_motif.c

  gui_motif.c: In function 'manage_centered':
  gui_motif.c:689: warning: missing sentinel in function call
  gui_motif.c:690: warning: missing sentinel in function call
  gui_motif.c:726: warning: missing sentinel in function call
  gui_motif.c: In function 'do_mnemonic':
  gui_motif.c:1996: warning: missing sentinel in function call
  gui_motif.c:2004: warning: missing sentinel in function call
  gui_motif.c:2011: warning: missing sentinel in function call
  gui_motif.c:2022: warning: missing sentinel in function call
  gui_motif.c: In function 'add_mnemonic_grabs':
  gui_motif.c:2076: warning: missing sentinel in function call
  gui_motif.c:2084: warning: missing sentinel in function call
  gui_motif.c:2091: warning: missing sentinel in function call

  gui_motif.c:

  689     XtVaGetValues(shell, XmNmappedWhenManaged, &mappedWhenManaged, 0);
  690     XtVaSetValues(shell, XmNmappedWhenManaged, False, 0);

  Declaration in /usr/include/X11/Intrinsic.h:

  extern void XtVaGetValues(
      Widget              /* widget */,
      ...
      ) _X_SENTINEL(0);

  The sentinel attribute is described in...
  http://gcc.gnu.org/onlinedocs/gcc-4.3.0/gcc/Function-Attributes.html#Function>
  It requires NULL (not 0) as last argument of XtVaGetValues(...).


2/ Crash (sometimes, not all the time) when exiting Vim or gvim when
   built with -DEXITFREE.

   Valgrind memory checker detects the following error:

   ==9224== Invalid read of size 4
   ==9224==    at 0x442AF1B: (within /usr/lib/libXt.so.6.0.0)
   ==9224==    by 0x441840A: XtCallCallbackList (in /usr/lib/libXt.so.6.0.0)
   ==9224==    by 0x44223FF: (within /usr/lib/libXt.so.6.0.0)
   ==9224==    by 0x4421C78: (within /usr/lib/libXt.so.6.0.0)
   ==9224==    by 0x4421D71: (within /usr/lib/libXt.so.6.0.0)
   ==9224==    by 0x442207C: _XtDoPhase2Destroy (in /usr/lib/libXt.so.6.0.0)
   ==9224==    by 0x44221F2: XtDestroyWidget (in /usr/lib/libXt.so.6.0.0)
   ==9224==    by 0x4422956: (within /usr/lib/libXt.so.6.0.0)
   ==9224==    by 0x4422E36: XtCloseDisplay (in /usr/lib/libXt.so.6.0.0)
   ==9224==    by 0x8141F42: mch_free_mem (os_unix.c:2894)
   ==9224==    by 0x810BE79: free_all_mem (misc2.c:1125)
   ==9224==    by 0x81420E5: mch_exit (os_unix.c:3012)
   ==9224==  Address 0x4dad72c is 52 bytes inside a block of size 64 free'd
   ==9224==    at 0x402265C: free (vg_replace_malloc.c:323)
   ==9224==    by 0x4417D90: XtFree (in /usr/lib/libXt.so.6.0.0)
   ==9224==    by 0x44223B8: (within /usr/lib/libXt.so.6.0.0)
   ==9224==    by 0x4421C78: (within /usr/lib/libXt.so.6.0.0)
   ==9224==    by 0x4421E01: (within /usr/lib/libXt.so.6.0.0)
   ==9224==    by 0x442207C: _XtDoPhase2Destroy (in /usr/lib/libXt.so.6.0.0)
   ==9224==    by 0x44221F2: XtDestroyWidget (in /usr/lib/libXt.so.6.0.0)
   ==9224==    by 0x4422956: (within /usr/lib/libXt.so.6.0.0)
   ==9224==    by 0x4422E36: XtCloseDisplay (in /usr/lib/libXt.so.6.0.0)
   ==9224==    by 0x8141F42: mch_free_mem (os_unix.c:2894)
   ==9224==    by 0x810BE79: free_all_mem (misc2.c:1125)
   ==9224==    by 0x81420E5: mch_exit (os_unix.c:3012)
  (more errors follow)

   XtCloseDisplay() accesses freed memory.  It looks like a bug
   in X11/Xt/Lesstif.

   I noticed that calls to XtCloseDisplay() & XtDestroyApplication()
   were already commented out in several places with the comment
   'Lesstif and Solaris crash here' in os_unix.c, but not commented
   out yet in mch_free_mem() where I observe the crash.   So I
   commented it out just like in other places.


3/ Memory leak in xsmp_close()

   ==10076== 38 bytes in 1 blocks are definitely lost in loss record 42 of 130
   ==10076==    at 0x4022AB8: malloc (vg_replace_malloc.c:207)
   ==10076==    by 0x43F1167: _SmcProcessMessage (in /usr/lib/libSM.so.6.0.0)
   ==10076==    by 0x4404AB2: IceProcessMessages (in /usr/lib/libICE.so.6.3.0)
   ==10076==    by 0x43ED5A2: SmcOpenConnection (in /usr/lib/libSM.so.6.0.0)
   ==10076==    by 0x8145F81: xsmp_init (os_unix.c:6596)
   ==10076==    by 0x80DE98C: main (main.c:496)

os_unix.c:

6595     /* Create an SM connection */
6596     xsmp.smcconn = SmcOpenConnection(
6597             NULL,
6598             NULL,
6599             SmProtoMajor,
6600             SmProtoMinor,
6601             SmcSaveYourselfProcMask | SmcDieProcMask
6602                      | SmcSaveCompleteProcMask |
SmcShutdownCancelledProcMask,
6603             &smcallbacks,
6604             NULL,
6605             &clientid,
6606             sizeof(errorstring),
6607             errorstring);

SmcOpenConnection() is documented there:

  http://www.cptec.inpe.br/sx4/sx4man2/g1ae04e/chap12.html

It says:

   If SmcOpenConnection succeeds, the function returns an opaque
   connection pointer of type SmcConn and the client_id_ret argument
   contains the client ID to be used for this session. ***client_id_ret
   should be freed with a call to free() when no longer needed.***

clientid is currently never freed in os_unix.c (hence leak).
I observe the leak when exiting, but since xsmp_close() is called
from other places too, so there may also be leaks even before exiting.

Attached patches:
- gui_motif.c.patch
- os_unix.c.patch

-- Dominique

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

Index: gui_motif.c
===================================================================
RCS file: /cvsroot/vim/vim7/src/gui_motif.c,v
retrieving revision 1.20
diff -c -r1.20 gui_motif.c
*** gui_motif.c	22 Jan 2008 10:06:37 -0000	1.20
--- gui_motif.c	7 Jun 2008 06:05:57 -0000
***************
*** 686,693 ****
  
      /* Temporarily set value of XmNmappedWhenManaged
         to stop the dialog from popping up right away */
!     XtVaGetValues(shell, XmNmappedWhenManaged, &mappedWhenManaged, 0);
!     XtVaSetValues(shell, XmNmappedWhenManaged, False, 0);
  
      XtManageChild(dialog_child);
  
--- 686,693 ----
  
      /* Temporarily set value of XmNmappedWhenManaged
         to stop the dialog from popping up right away */
!     XtVaGetValues(shell, XmNmappedWhenManaged, &mappedWhenManaged, NULL);
!     XtVaSetValues(shell, XmNmappedWhenManaged, False, NULL);
  
      XtManageChild(dialog_child);
  
***************
*** 723,729 ****
      XtMapWidget(shell);
  
      /* Restore the value of XmNmappedWhenManaged */
!     XtVaSetValues(shell, XmNmappedWhenManaged, mappedWhenManaged, 0);
  }
  
  #if defined(FEAT_MENU) || defined(FEAT_SUN_WORKSHOP) \
--- 723,729 ----
      XtMapWidget(shell);
  
      /* Restore the value of XmNmappedWhenManaged */
!     XtVaSetValues(shell, XmNmappedWhenManaged, mappedWhenManaged, NULL);
  }
  
  #if defined(FEAT_MENU) || defined(FEAT_SUN_WORKSHOP) \
***************
*** 1355,1362 ****
  	}
  	else
  	{
! 	    /* Without shadows one can't sense whatever the button has been
! 	     * pressed or not! However we wan't to save a bit of space...
  	     * Need the highlightThickness to see the focus.
  	     */
  	    XtSetArg(args[n], XmNhighlightThickness, 1); n++;
--- 1355,1362 ----
  	}
  	else
  	{
! 	    /* Without shadows one can't sense whether the button has been
! 	     * pressed or not! However we want to save a bit of space...
  	     * Need the highlightThickness to see the focus.
  	     */
  	    XtSetArg(args[n], XmNhighlightThickness, 1); n++;
***************
*** 1993,1999 ****
      {
  	if (XtClass(w) == xmRowColumnWidgetClass)
  	{
! 	    XtVaGetValues(w, XmNrowColumnType, &rowColType, 0);
  	    isMenu = (rowColType != (unsigned char)XmWORK_AREA);
  	}
  	else
--- 1993,1999 ----
      {
  	if (XtClass(w) == xmRowColumnWidgetClass)
  	{
! 	    XtVaGetValues(w, XmNrowColumnType, &rowColType, NULL);
  	    isMenu = (rowColType != (unsigned char)XmWORK_AREA);
  	}
  	else
***************
*** 2001,2014 ****
  	if (!isMenu)
  	{
  	    XtVaGetValues(w, XmNchildren, &children, XmNnumChildren,
! 			  &numChildren, 0);
  	    for (i = 0; i < numChildren; i++)
  		do_mnemonic(children[i], keycode);
  	}
      }
      else
      {
! 	XtVaGetValues(w, XmNmnemonic, &mnemonic, 0);
  	if (mnemonic != '\0')
  	{
  	    mneString[0] = mnemonic;
--- 2001,2014 ----
  	if (!isMenu)
  	{
  	    XtVaGetValues(w, XmNchildren, &children, XmNnumChildren,
! 			  &numChildren, NULL);
  	    for (i = 0; i < numChildren; i++)
  		do_mnemonic(children[i], keycode);
  	}
      }
      else
      {
! 	XtVaGetValues(w, XmNmnemonic, &mnemonic, NULL);
  	if (mnemonic != '\0')
  	{
  	    mneString[0] = mnemonic;
***************
*** 2019,2025 ****
  		if (XtClass(w) == xmLabelWidgetClass
  			|| XtClass(w) == xmLabelGadgetClass)
  		{
! 		    XtVaGetValues(w, XmNuserData, &userData, 0);
  		    if (userData != NULL && XtIsWidget(userData))
  			XmProcessTraversal(userData, XmTRAVERSE_CURRENT);
  		}
--- 2019,2025 ----
  		if (XtClass(w) == xmLabelWidgetClass
  			|| XtClass(w) == xmLabelGadgetClass)
  		{
! 		    XtVaGetValues(w, XmNuserData, &userData, NULL);
  		    if (userData != NULL && XtIsWidget(userData))
  			XmProcessTraversal(userData, XmTRAVERSE_CURRENT);
  		}
***************
*** 2073,2079 ****
      {
  	if (XtClass(w) == xmRowColumnWidgetClass)
  	{
! 	    XtVaGetValues(w, XmNrowColumnType, &rowColType, 0);
  	    isMenu = (rowColType != (unsigned char)XmWORK_AREA);
  	}
  	else
--- 2073,2079 ----
      {
  	if (XtClass(w) == xmRowColumnWidgetClass)
  	{
! 	    XtVaGetValues(w, XmNrowColumnType, &rowColType, NULL);
  	    isMenu = (rowColType != (unsigned char)XmWORK_AREA);
  	}
  	else
***************
*** 2081,2094 ****
  	if (!isMenu)
  	{
  	    XtVaGetValues(w, XmNchildren, &children, XmNnumChildren,
! 							     &numChildren, 0);
  	    for (i = 0; i < numChildren; i++)
  		add_mnemonic_grabs(dialog, children[i]);
  	}
      }
      else
      {
! 	XtVaGetValues(w, XmNmnemonic, &mnemonic, 0);
  	if (mnemonic != '\0')
  	{
  	    mneString[0] = mnemonic;
--- 2081,2094 ----
  	if (!isMenu)
  	{
  	    XtVaGetValues(w, XmNchildren, &children, XmNnumChildren,
! 							     &numChildren, NULL);
  	    for (i = 0; i < numChildren; i++)
  		add_mnemonic_grabs(dialog, children[i]);
  	}
      }
      else
      {
! 	XtVaGetValues(w, XmNmnemonic, &mnemonic, NULL);
  	if (mnemonic != '\0')
  	{
  	    mneString[0] = mnemonic;
***************
*** 3234,3240 ****
  # ifdef FEAT_FOOTER
  /*
   * The next toolbar enter/leave callbacks should really do balloon help.  But
!  * I have to use footer help for backwards compatability.  Hopefully both will
   * get implemented and the user will have a choice.
   */
  /*ARGSUSED*/
--- 3234,3240 ----
  # ifdef FEAT_FOOTER
  /*
   * The next toolbar enter/leave callbacks should really do balloon help.  But
!  * I have to use footer help for backwards compatibility.  Hopefully both will
   * get implemented and the user will have a choice.
   */
  /*ARGSUSED*/
***************
*** 4105,4111 ****
  }
  
  /*
!  * Synchronize all gui elements, which are dependant upon the
   * main text font used. Those are in esp. the find/replace dialogs.
   * If you don't understand why this should be needed, please try to
   * search for "piê¶æ" in iso8859-2.
--- 4105,4111 ----
  }
  
  /*
!  * Synchronize all gui elements, which are dependent upon the
   * main text font used. Those are in esp. the find/replace dialogs.
   * If you don't understand why this should be needed, please try to
   * search for "piê¶æ" in iso8859-2.
Index: os_unix.c
===================================================================
RCS file: /cvsroot/vim/vim7/src/os_unix.c,v
retrieving revision 1.80
diff -c -r1.80 os_unix.c
*** os_unix.c	7 May 2008 17:07:38 -0000	1.80
--- os_unix.c	7 Jun 2008 06:06:09 -0000
***************
*** 209,214 ****
--- 209,215 ----
  {
      SmcConn smcconn;	    /* The SM connection ID */
      IceConn iceconn;	    /* The ICE connection ID */
+     char *clientid;         /* The client ID for the current smc session */
      Bool save_yourself;     /* If we're in the middle of a save_yourself */
      Bool shutdown;	    /* If we're in shutdown mode */
  } xsmp_config_T;
***************
*** 2890,2899 ****
--- 2891,2903 ----
  # if (defined(FEAT_X11) && defined(FEAT_XCLIPBOARD)) || defined(PROTO)
      if (xterm_Shell != (Widget)0)
  	XtDestroyWidget(xterm_Shell);
+ #if 0
+     /* Lesstif crashes here, lose some memory */
      if (xterm_dpy != NULL)
  	XtCloseDisplay(xterm_dpy);
      if (app_context != (XtAppContext)NULL)
  	XtDestroyApplicationContext(app_context);
+ #endif
  # endif
  # ifdef FEAT_X11
      if (x11_display != NULL && x11_display != xterm_dpy)
***************
*** 6557,6563 ****
  xsmp_init(void)
  {
      char		errorstring[80];
-     char		*clientid;
      SmcCallbacks	smcallbacks;
  #if 0
      SmPropValue		smname;
--- 6561,6566 ----
***************
*** 6599,6605 ****
  		     | SmcSaveCompleteProcMask | SmcShutdownCancelledProcMask,
  	    &smcallbacks,
  	    NULL,
! 	    &clientid,
  	    sizeof(errorstring),
  	    errorstring);
      if (xsmp.smcconn == NULL)
--- 6602,6608 ----
  		     | SmcSaveCompleteProcMask | SmcShutdownCancelledProcMask,
  	    &smcallbacks,
  	    NULL,
! 	    &xsmp.clientid,
  	    sizeof(errorstring),
  	    errorstring);
      if (xsmp.smcconn == NULL)
***************
*** 6638,6643 ****
--- 6641,6648 ----
      if (xsmp_icefd != -1)
      {
  	SmcCloseConnection(xsmp.smcconn, 0, NULL);
+ 	vim_free(xsmp.clientid);
+ 	xsmp.clientid = NULL;
  	xsmp_icefd = -1;
      }
  }

Raspunde prin e-mail lui