[glib/wip/gcleanup: 9/21] gcleanup: Add some debugging code for tracing gcleanup
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/wip/gcleanup: 9/21] gcleanup: Add some debugging code for tracing gcleanup
- Date: Thu, 7 Nov 2013 07:21:24 +0000 (UTC)
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]