[Xfce4-commits] <xfce4-appfinder:master> Add refcount debugging.

Nick Schermer noreply at xfce.org
Wed Dec 28 12:32:04 CET 2011


Updating branch refs/heads/master
         to 50ec0c25d28ba896fb2f71835f207c52cd8f202b (commit)
       from e72f82380304d9a6263b6ad860dd513b188f04dc (commit)

commit 50ec0c25d28ba896fb2f71835f207c52cd8f202b
Author: Nick Schermer <nick at xfce.org>
Date:   Wed Dec 28 11:55:44 2011 +0100

    Add refcount debugging.
    
    Monitor destruction of almost every object created
    during the lifetime of the appfinder, including everthing
    we parse from garcon and pixbufs that are generated.
    
    So many things are reffed and unreffed it is hard to track
    if everything works as expected, this should help a bit.

 src/appfinder-actions.c        |    1 +
 src/appfinder-category-model.c |    7 +++-
 src/appfinder-model.c          |   20 ++++++++++-
 src/appfinder-private.h        |    7 ++++
 src/main.c                     |   76 ++++++++++++++++++++++++++++++++++++++++
 5 files changed, 108 insertions(+), 3 deletions(-)

diff --git a/src/appfinder-actions.c b/src/appfinder-actions.c
index 0324a65..e3d4d9a 100644
--- a/src/appfinder-actions.c
+++ b/src/appfinder-actions.c
@@ -505,6 +505,7 @@ xfce_appfinder_actions_get (void)
     {
       actions = g_object_new (XFCE_TYPE_APPFINDER_ACTIONS, NULL);
       g_object_add_weak_pointer (G_OBJECT (actions), (gpointer) &actions);
+      appfinder_refcount_debug_add (G_OBJECT (actions), "actions");
     }
 
   return actions;
diff --git a/src/appfinder-category-model.c b/src/appfinder-category-model.c
index efb2f3e..243aaeb 100644
--- a/src/appfinder-category-model.c
+++ b/src/appfinder-category-model.c
@@ -145,6 +145,7 @@ xfce_appfinder_category_model_init (XfceAppfinderCategoryModel *model)
   model->all_applications = g_object_new (GARCON_TYPE_MENU_DIRECTORY,
                                           "name", _("All Applications"),
                                           "icon-name", "applications-other", NULL);
+  appfinder_refcount_debug_add (G_OBJECT (model->all_applications), "all-applications");
 }
 
 
@@ -471,7 +472,9 @@ xfce_appfinder_category_category_free (CategoryItem *item)
 XfceAppfinderCategoryModel *
 xfce_appfinder_category_model_new (void)
 {
-  return g_object_new (XFCE_TYPE_APPFINDER_CATEGORY_MODEL, NULL);
+  gpointer model = g_object_new (XFCE_TYPE_APPFINDER_CATEGORY_MODEL, NULL);
+  appfinder_refcount_debug_add (G_OBJECT (model), "category-model");
+  return model;
 }
 
 
@@ -503,7 +506,7 @@ xfce_appfinder_category_model_set_categories (XfceAppfinderCategoryModel *model,
      gtk_tree_path_free (path);
 
      /* cleanup structures */
-     g_slist_foreach (model->categories, (GFunc)xfce_appfinder_category_category_free, NULL); 
+     g_slist_foreach (model->categories, (GFunc)xfce_appfinder_category_category_free, NULL);
      g_slist_free (model->categories);
      model->categories = NULL;
     }
diff --git a/src/appfinder-model.c b/src/appfinder-model.c
index edc232d..65112f2 100644
--- a/src/appfinder-model.c
+++ b/src/appfinder-model.c
@@ -218,6 +218,8 @@ xfce_appfinder_model_init (XfceAppfinderModel *model)
   model->collect_cancelled = g_cancellable_new ();
 
   model->menu = garcon_menu_new_applications ();
+  appfinder_refcount_debug_add (G_OBJECT (model->menu), "main menu");
+
   model->collect_thread = g_thread_create (xfce_appfinder_model_collect_thread, model, TRUE, NULL);
 }
 
@@ -838,6 +840,9 @@ xfce_appfinder_model_item_new (GarconMenuItem *menu_item)
   item = g_slice_new0 (ModelItem);
   item->item = g_object_ref (G_OBJECT (menu_item));
 
+  appfinder_refcount_debug_add (G_OBJECT (menu_item),
+     garcon_menu_item_get_desktop_id (menu_item));
+
   command = garcon_menu_item_get_command (menu_item);
   if (G_LIKELY (command != NULL))
     {
@@ -1152,6 +1157,7 @@ xfce_appfinder_model_history_monitor (XfceAppfinderModel *model,
 
       /* monitor the file for changes */
       model->history_monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, model->collect_cancelled, &error);
+      appfinder_refcount_debug_add (G_OBJECT (model->history_monitor), "history file monitor");
       if (model->history_monitor != NULL)
         {
           APPFINDER_DEBUG ("monitor history file %s", path);
@@ -1316,6 +1322,9 @@ xfce_appfinder_model_collect_items (GarconMenu           *menu,
   directory = garcon_menu_get_directory (menu);
   if (directory != NULL)
     {
+      appfinder_refcount_debug_add (G_OBJECT (directory),
+          garcon_menu_directory_get_name (directory));
+
       if (!garcon_menu_directory_get_visible (directory))
         return FALSE;
 
@@ -1356,9 +1365,14 @@ xfce_appfinder_model_collect_items (GarconMenu           *menu,
   menus = garcon_menu_get_menus (menu);
   for (li = menus; li != NULL; li = li->next)
     {
+      appfinder_refcount_debug_add (G_OBJECT (li->data),
+          garcon_menu_element_get_name (li->data));
+
       if (xfce_appfinder_model_collect_items (li->data, cancelled, category, items,
                                               categories, desktop_ids))
-        has_items = TRUE;
+        {
+          has_items = TRUE;
+        }
     }
   g_list_free (menus);
 
@@ -1648,6 +1662,7 @@ xfce_appfinder_model_get (void)
     {
       model = g_object_new (XFCE_TYPE_APPFINDER_MODEL, NULL);
       g_object_add_weak_pointer (G_OBJECT (model), (gpointer) &model);
+      appfinder_refcount_debug_add (G_OBJECT (model), "appfinder-model");
       APPFINDER_DEBUG ("allocate new model");
     }
 
@@ -1930,6 +1945,8 @@ xfce_appfinder_model_load_pixbuf (const gchar           *icon_name,
       pixbuf = scaled;
     }
 
+  appfinder_refcount_debug_add (G_OBJECT (pixbuf), icon_name);
+
   return pixbuf;
 }
 
@@ -2119,6 +2136,7 @@ xfce_appfinder_model_get_command_category (void)
                                "name", _("Commands History"),
                                "icon-name", GTK_STOCK_EXECUTE,
                                NULL);
+      appfinder_refcount_debug_add (G_OBJECT (category), "commands");
       g_object_add_weak_pointer (G_OBJECT (category), (gpointer) &category);
     }
 
diff --git a/src/appfinder-private.h b/src/appfinder-private.h
index 7b3cb54..9cb4d44 100644
--- a/src/appfinder-private.h
+++ b/src/appfinder-private.h
@@ -34,6 +34,13 @@ G_STMT_START { \
 #endif
 
 #ifdef DEBUG
+void    appfinder_refcount_debug_add (GObject     *object,
+                                      const gchar *description);
+#else
+#define appfinder_refcount_debug_add(object, description) G_STMT_START{ (void)0; }G_STMT_END
+#endif
+
+#ifdef DEBUG
 #define appfinder_assert(expr)                 g_assert (expr)
 #define appfinder_assert_not_reached()         g_assert_not_reached ()
 #define appfinder_return_if_fail(expr)         g_return_if_fail (expr)
diff --git a/src/main.c b/src/main.c
index edca5bb..d7b2e5d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -63,6 +63,11 @@ static GSList             *windows = NULL;
 static gboolean            service_owner = FALSE;
 static XfceAppfinderModel *model_cache = NULL;
 
+#ifdef DEBUG
+static GHashTable         *objects_table = NULL;
+static guint               objects_table_count = 0;
+#endif
+
 
 
 static GOptionEntry option_entries[] =
@@ -81,6 +86,68 @@ static void appfinder_dbus_unregister (DBusConnection *dbus_connection);
 
 
 
+#ifdef DEBUG
+static void
+appfinder_refcount_debug_weak_notify (gpointer  data,
+                                      GObject  *where_the_object_was)
+{
+  /* remove the unreffed object pixbuf from the table */
+  if (!g_hash_table_remove (objects_table, where_the_object_was))
+    appfinder_assert_not_reached ();
+}
+
+
+
+static void
+appfinder_refcount_debug_print (gpointer object,
+                                gpointer desc,
+                                gpointer data)
+{
+  APPFINDER_DEBUG ("object %p (type = %s, desc = %s) not released",
+                   object, G_OBJECT_TYPE_NAME (object), (gchar *) desc);
+}
+
+
+
+void
+appfinder_refcount_debug_add (GObject     *object,
+                              const gchar *description)
+{
+  /* silently ignore objects that are already registered */
+  if (object != NULL
+      && g_hash_table_lookup (objects_table, object) == NULL)
+    {
+      objects_table_count++;
+      g_object_weak_ref (G_OBJECT (object), appfinder_refcount_debug_weak_notify, NULL);
+      g_hash_table_insert (objects_table, object, g_strdup (description));
+    }
+}
+
+
+
+static void
+appfinder_refcount_debug_init (void)
+{
+  objects_table = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
+}
+
+
+
+static void
+appfinder_refcount_debug_finalize (void)
+{
+  /* leakup refcount hashtable */
+  APPFINDER_DEBUG ("%d objects leaked, %d registered",
+                   g_hash_table_size (objects_table),
+                   objects_table_count);
+
+  g_hash_table_foreach (objects_table, appfinder_refcount_debug_print, NULL);
+  g_hash_table_destroy (objects_table);
+}
+#endif
+
+
+
 static void
 appfinder_window_destroyed (GtkWidget *window)
 {
@@ -113,6 +180,7 @@ appfinder_window_new (const gchar *startup_id,
   window = g_object_new (XFCE_TYPE_APPFINDER_WINDOW,
                          "startup-id", IS_STRING (startup_id) ? startup_id : NULL,
                          NULL);
+  appfinder_refcount_debug_add (G_OBJECT (window), startup_id);
   xfce_appfinder_window_set_expanded (XFCE_APPFINDER_WINDOW (window), expanded);
   gtk_widget_show (window);
 
@@ -485,6 +553,10 @@ main (gint argc, gchar **argv)
        return EXIT_FAILURE;
     }
 
+#ifdef DEBUG
+  appfinder_refcount_debug_init ();
+#endif
+
   /* create initial window */
   appfinder_window_new (NULL, !opt_collapsed);
 
@@ -515,5 +587,9 @@ main (gint argc, gchar **argv)
 
   xfconf_shutdown ();
 
+#ifdef DEBUG
+  appfinder_refcount_debug_finalize ();
+#endif
+
   return EXIT_SUCCESS;
 }


More information about the Xfce4-commits mailing list