[glib/wip/gcleanup: 9/21] gcleanup: Add some debugging code for tracing gcleanup



commit 87cc44da296174de10105714ba5fd1f61b581028
Author: Stef Walter <stefw gnome org>
Date:   Thu Oct 31 11:42:32 2013 +0100

    gcleanup: Add some debugging code for tracing gcleanup
    
    I used this while developing the remander of these patches, and it's
    very helpful to track things down. May need a more dynamic way to
    enable, such as using one of the slots in GCleanupList.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=627423

 glib/gcleanup.c |   25 ++++++++++++++++++++++---
 glib/gcleanup.h |   22 ++++++++++++++++------
 2 files changed, 38 insertions(+), 9 deletions(-)
---
diff --git a/glib/gcleanup.c b/glib/gcleanup.c
index 89960c3..092bd8b 100644
--- a/glib/gcleanup.c
+++ b/glib/gcleanup.c
@@ -26,14 +26,23 @@
 
 #include <stdlib.h>
 
+/*
+ * NOTE: most glib functions are off limits in this function without
+ * careful consideration. In particular error printing and logging functions,
+ * use various locks, which would cause issues during cleanup.
+ */
+
+#include <stdio.h>
+
 /* As good a place as any to put this... */
-G_CLEANUP_DEFINE
+G_CLEANUP_DEFINE (G_CLEANUP_NORMAL);
 
 typedef struct _GCleanupNode GCleanupNode;
 struct _GCleanupNode
 {
   GDestroyNotify  func;
   gpointer        data;
+  const gchar    *code_loc;
   GCleanupNode   *next;
 };
 
@@ -66,6 +75,7 @@ g_cleanup_is_enabled (void)
  * @list: a #GCleanupList
  * @cleanup_func: the cleanup function
  * @user_data: data for the cleanup function
+ * @code_loc: (allow-none): static string representing location of this call (ie: G_STRLOC)
  *
  * Adds a function to @list.
  *
@@ -83,7 +93,8 @@ g_cleanup_is_enabled (void)
 void
 g_cleanup_list_add (GCleanupList *list,
                     GCleanupFunc  cleanup_func,
-                    gpointer      user_data)
+                    gpointer      user_data,
+                    const gchar  *code_loc)
 {
   GCleanupNode *node;
 
@@ -95,11 +106,15 @@ g_cleanup_list_add (GCleanupList *list,
   node = malloc (sizeof (GCleanupNode));
   node->func = cleanup_func;
   node->data = user_data;
+  node->code_loc = code_loc;
 
   g_mutex_lock (&lock);
   node->next = list->priv[0];
   list->priv[0] = node;
   g_mutex_unlock (&lock);
+
+  if (list->vals[0] & G_CLEANUP_VERBOSE)
+    fprintf (stderr, "GLib-Cleanup: added: %s %p\n", code_loc, user_data);
 }
 
 /**
@@ -122,13 +137,17 @@ g_cleanup_list_add (GCleanupList *list,
 void
 g_cleanup_list_clear (GCleanupList *list)
 {
+  gboolean verbose;
+
   if (!g_cleanup_enabled)
     return;
 
+  verbose = list->vals[0] & G_CLEANUP_VERBOSE;
   while (list->priv[0])
     {
       GCleanupNode *node = list->priv[0];
-
+      if (verbose)
+        fprintf (stderr, "GLib-Cleanup: cleanup: %s %p\n", node->code_loc, node->data);
       (* node->func) (node->data);
       list->priv[0] = node->next;
       free (node);
diff --git a/glib/gcleanup.h b/glib/gcleanup.h
index 27ae2bb..4b12606 100644
--- a/glib/gcleanup.h
+++ b/glib/gcleanup.h
@@ -34,8 +34,15 @@ G_BEGIN_DECLS
 typedef struct
 {
   gpointer priv[4];
+  gint     vals[4];
 } GCleanupList;
 
+typedef enum
+{
+  G_CLEANUP_NORMAL = 0,
+  G_CLEANUP_VERBOSE = 1 << 0,
+} GCleanupFlags;
+
 typedef void (* GCleanupFunc) (gpointer user_data);
 
 GLIB_AVAILABLE_IN_2_36
@@ -43,15 +50,16 @@ gboolean                g_cleanup_is_enabled                            (void);
 GLIB_AVAILABLE_IN_2_36
 void                    g_cleanup_list_add                              (GCleanupList *list,
                                                                          GCleanupFunc  cleanup_func,
-                                                                         gpointer      user_data);
+                                                                         gpointer      user_data,
+                                                                         const gchar * code_loc);
 GLIB_AVAILABLE_IN_2_36
 void                    g_cleanup_list_clear                            (GCleanupList *list);
 
 
 #if defined(G_HAS_CONSTRUCTORS) && !defined(G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA)
 
-#define G_CLEANUP_DEFINE \
-  GCleanupList _glib_cleanup_list;                                              \
+#define G_CLEANUP_DEFINE(flags) \
+  GCleanupList _glib_cleanup_list = { { 0, }, { flags, } };                     \
   G_DEFINE_DESTRUCTOR (_glib_do_cleanup)                                        \
   static void _glib_do_cleanup (void) {                                         \
     g_cleanup_list_clear (&_glib_cleanup_list);                                 \
@@ -60,18 +68,20 @@ void                    g_cleanup_list_clear                            (GCleanu
   G_STMT_START {                                                                \
     extern GCleanupList _glib_cleanup_list;                                     \
     if (0) (func) ((data));                                                     \
-    g_cleanup_list_add (&_glib_cleanup_list, (void*) (func), (data));           \
+    g_cleanup_list_add (&_glib_cleanup_list, (void*) (func), (data),            \
+                        G_STRLOC ": " G_STRINGIFY (func));                      \
   } G_STMT_END
 #define G_CLEANUP_ADD_FUNC(func) \
   G_STMT_START {                                                                \
     extern GCleanupList _glib_cleanup_list;                                     \
     if (0) (func) ();                                                           \
-    g_cleanup_list_add (&_glib_cleanup_list, (void*) (func), NULL);             \
+    g_cleanup_list_add (&_glib_cleanup_list, (void*) (func), NULL,              \
+                        G_STRLOC ": " G_STRINGIFY (func));                      \
   } G_STMT_END
 
 #else
 
-#define G_CLEANUP_DEFINE
+#define G_CLEANUP_DEFINE(flags)
 #define G_CLEANUP_ADD(data, func) \
   G_STMT_START {                                                        \
     if (0) (func) (data);                                               \


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]