[evolution-data-server] Merge same backtraces into one e_pointer_tracker report
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Merge same backtraces into one e_pointer_tracker report
- Date: Fri, 29 Jul 2011 16:55:58 +0000 (UTC)
commit eb1aa6446b0d2d9677a6f7abef64e9c08314e329
Author: Milan Crha <mcrha redhat com>
Date: Fri Jul 29 18:54:45 2011 +0200
Merge same backtraces into one e_pointer_tracker report
libedataserver/e-data-server-util.c | 83 +++++++++++++++++++++++++++++++++-
1 files changed, 80 insertions(+), 3 deletions(-)
---
diff --git a/libedataserver/e-data-server-util.c b/libedataserver/e-data-server-util.c
index 676c862..7fac72f 100644
--- a/libedataserver/e-data-server-util.c
+++ b/libedataserver/e-data-server-util.c
@@ -921,6 +921,7 @@ G_LOCK_DEFINE_STATIC (ptr_tracker);
static GHashTable *ptr_tracker = NULL;
struct pt_data {
+ gpointer ptr;
gchar *info;
GString *backtrace;
};
@@ -940,17 +941,88 @@ free_pt_data (gpointer ptr)
}
static void
-dump_left_ptrs_cb (gpointer ptr, gpointer info, gpointer user_data)
+dump_left_ptrs_cb (gpointer key, gpointer value, gpointer user_data)
{
guint *left = user_data;
- struct pt_data *ptd = info;
+ struct pt_data *ptd = value;
gboolean have_info = ptd && ptd->info;
gboolean have_bt = ptd && ptd->backtrace && ptd->backtrace->str && *ptd->backtrace->str;
*left = (*left) - 1;
- g_print (" %p %s%s%s%s%s%s\n", ptr, have_info ? "(" : "", have_info ? ptd->info : "", have_info ? ")" : "", have_bt ? "\n" : "", have_bt ? ptd->backtrace->str : "", have_bt && *left > 0 ? "\n" : "");
+ g_print (" %p %s%s%s%s%s%s\n", key, have_info ? "(" : "", have_info ? ptd->info : "", have_info ? ")" : "", have_bt ? "\n" : "", have_bt ? ptd->backtrace->str : "", have_bt && *left > 0 ? "\n" : "");
}
+#ifdef HAVE_BACKTRACE_SYMBOLS
+static guint
+by_backtrace_hash (gconstpointer ptr)
+{
+ const struct pt_data *ptd = ptr;
+
+ if (!ptd || !ptd->backtrace)
+ return 0;
+
+ return g_str_hash (ptd->backtrace->str);
+}
+
+static gboolean
+by_backtrace_equal (gconstpointer ptr1, gconstpointer ptr2)
+{
+ const struct pt_data *ptd1 = ptr1, *ptd2 = ptr2;
+
+ if ((!ptd1 || !ptd1->backtrace) && (!ptd2 || !ptd2->backtrace))
+ return TRUE;
+
+ return ptd1 && ptd1->backtrace && ptd2 && ptd2->backtrace && g_str_equal (ptd1->backtrace->str, ptd2->backtrace->str);
+}
+
+static void
+dump_by_backtrace_cb (gpointer key, gpointer value, gpointer user_data)
+{
+ guint *left = user_data;
+ struct pt_data *ptd = key;
+ guint count = GPOINTER_TO_UINT (value);
+
+ if (count == 1) {
+ dump_left_ptrs_cb (ptd->ptr, ptd, left);
+ } else {
+ gboolean have_info = ptd && ptd->info;
+ gboolean have_bt = ptd && ptd->backtrace && ptd->backtrace->str && *ptd->backtrace->str;
+
+ *left = (*left) - 1;
+
+ g_print (" %d x %s%s%s%s%s%s\n", count, have_info ? "(" : "", have_info ? ptd->info : "", have_info ? ")" : "", have_bt ? "\n" : "", have_bt ? ptd->backtrace->str : "", have_bt && *left > 0 ? "\n" : "");
+ }
+}
+
+static void
+dump_by_backtrace (GHashTable *ptrs)
+{
+ GHashTable *by_bt = g_hash_table_new (by_backtrace_hash, by_backtrace_equal);
+ GHashTableIter iter;
+ gpointer key, value;
+ struct ptr_data *ptd;
+ guint count;
+
+ g_hash_table_iter_init (&iter, ptrs);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ guint cnt;
+
+ ptd = value;
+ if (!ptd)
+ continue;
+
+ cnt = GPOINTER_TO_UINT (g_hash_table_lookup (by_bt, ptd));
+ cnt++;
+
+ g_hash_table_insert (by_bt, ptd, GUINT_TO_POINTER (cnt));
+ }
+
+ count = g_hash_table_size (by_bt);
+ g_hash_table_foreach (by_bt, dump_by_backtrace_cb, &count);
+ g_hash_table_destroy (by_bt);
+}
+#endif /* HAVE_BACKTRACE_SYMBOLS */
+
static void
dump_tracked_ptrs (gboolean is_at_exit)
{
@@ -963,7 +1035,11 @@ dump_tracked_ptrs (gboolean is_at_exit)
} else {
guint count = g_hash_table_size (ptr_tracker);
g_print (" Left %d tracked pointers:\n", count);
+ #ifdef HAVE_BACKTRACE_SYMBOLS
+ dump_by_backtrace (ptr_tracker);
+ #else
g_hash_table_foreach (ptr_tracker, dump_left_ptrs_cb, &count);
+ #endif
}
g_print ("----------------------------------------------------------\n");
} else if (!is_at_exit) {
@@ -1169,6 +1245,7 @@ e_pointer_tracker_track_with_info (gpointer ptr, const gchar *info)
}
ptd = g_new0 (struct pt_data, 1);
+ ptd->ptr = ptr;
ptd->info = g_strdup (info);
ptd->backtrace = get_current_backtrace ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]