GtkMenuItem Memory Leak reported by Valgrind
I have been running Valgrind on gtk based applications and have found a memory leak in gtkmenuitem.c. My setup is: Linux Mint 19.1 Tessa (up to date) with: libgtk-3-0 version: 3.22.30-1ubuntu2.1 libglib2.0-0 version: 2.56.3-0ubuntu0.18.04.1
Memory is leaked when the popup menu does not popup and timeout is cancelled. Below is a cut & paste of a personal use patch I created to plug the leak of the memory allocated for 'PopupInfo' struct. I have tested the change and it works fine under my system configuration, and valgrind no longer reports the leak. I have only tested the change with my setup so have no idea how they may affect other things. Looking thru the source code on gitlab I see the bug still appears to exist in the latest master (code slightly different though).
I hope the info here helps!
diff -NZuarp gtk+3.0-3.22.30/gtk/gtkmenuitem.c gtk+3.0-3.22.30/gtk/gtkmenuitem.c
--- gtk+3.0-3.22.30/gtk/gtkmenuitem.c 2018-01-09 12:28:23.000000000 -0800
+++ gtk+3.0-3.22.30/gtk/gtkmenuitem.c 2019-03-02 19:20:00.942438150 -0800
@@ -2080,6 +2080,13 @@ typedef struct
GdkEvent *trigger_event;
} PopupInfo;
+// BUGFIX: plug submenu memory leak
+static void popup_free_func(PopupInfo *info)
+{
+ g_clear_pointer (&info->trigger_event, gdk_event_free);
+ g_slice_free (PopupInfo, info);
+}
+
static gint
gtk_menu_item_popup_timeout (gpointer data)
{
@@ -2103,8 +2110,7 @@ gtk_menu_item_popup_timeout (gpointer da
priv->timer = 0;
- g_clear_pointer (&info->trigger_event, gdk_event_free);
- g_slice_free (PopupInfo, info);
+ // BUGFIX: submenu issues - PopupInfo *info now destroyed in popup_free_func
return FALSE;
}
@@ -2146,9 +2152,10 @@ _gtk_menu_item_popup_submenu (GtkWidget
info->menu_item = menu_item;
info->trigger_event = gtk_get_current_event ();
- priv->timer = gdk_threads_add_timeout (popup_delay,
+ // BUGFIX: submenu issues
+ priv->timer = gdk_threads_add_timeout_full (G_PRIORITY_DEFAULT, popup_delay,
gtk_menu_item_popup_timeout,
- info);
+ info, (GDestroyNotify) popup_free_func);
g_source_set_name_by_id (priv->timer, "[gtk+] gtk_menu_item_popup_timeout");
return;