[evolution-data-server] Move e_pointer_tracker to camel



commit e54481ecc147ddace454ccce6a06d27ff560252b
Author: Milan Crha <mcrha redhat com>
Date:   Thu Jul 26 18:42:30 2012 +0200

    Move e_pointer_tracker to camel
    
    Thus it can be used in camel (and elsewhere) again.

 camel/Makefile.am                   |    3 +-
 camel/camel-debug.c                 |  425 +++++++++++++++++++++++++++++++++++
 camel/camel-debug.h                 |   23 ++
 configure.ac                        |    2 +-
 libedataserver/Makefile.am          |    3 +-
 libedataserver/e-data-server-util.c |  402 ---------------------------------
 libedataserver/e-data-server-util.h |   14 --
 7 files changed, 452 insertions(+), 420 deletions(-)
---
diff --git a/camel/Makefile.am b/camel/Makefile.am
index 031eb38..5815d70 100644
--- a/camel/Makefile.am
+++ b/camel/Makefile.am
@@ -329,7 +329,8 @@ libcamel_1_2_la_LIBADD =				\
 	$(CAMEL_LIBS)					\
 	$(SOCKET_LIBS)					\
 	$(ICONV_LIBS)					\
-	$(REGEX_LIBS)
+	$(REGEX_LIBS)					\
+	$(LIBDWFL_LIBS)
 
 camel_lock_helper_1_2_CPPFLAGS = \
 	$(AM_CPPFLAGS)						\
diff --git a/camel/camel-debug.c b/camel/camel-debug.c
index 6509475..4f35e1b 100644
--- a/camel/camel-debug.c
+++ b/camel/camel-debug.c
@@ -19,10 +19,23 @@
  * USA
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
+#ifdef HAVE_BACKTRACE_SYMBOLS
+#include <execinfo.h>
+#ifdef HAVE_ELFUTILS_LIBDWFL
+#include <elfutils/libdwfl.h>
+#include <errno.h>
+#include <unistd.h>
+#endif
+#endif
+
 #include "camel-debug.h"
 
 gint camel_verbose_debug;
@@ -247,3 +260,415 @@ camel_debug_hwatch (gint wp,
 }
 
 #endif
+
+G_LOCK_DEFINE_STATIC (ptr_tracker);
+static GHashTable *ptr_tracker = NULL;
+
+struct pt_data {
+	gpointer ptr;
+	gchar *info;
+	GString *backtrace;
+};
+
+static void
+free_pt_data (gpointer ptr)
+{
+	struct pt_data *ptd = ptr;
+
+	if (!ptd)
+		return;
+
+	g_free (ptd->info);
+	if (ptd->backtrace)
+		g_string_free (ptd->backtrace, TRUE);
+	g_free (ptd);
+}
+
+static void
+dump_left_ptrs_cb (gpointer key,
+                   gpointer value,
+                   gpointer user_data)
+{
+	guint *left = user_data;
+	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", 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)
+{
+	G_LOCK (ptr_tracker);
+
+	if (ptr_tracker) {
+		g_print ("\n----------------------------------------------------------\n");
+		if (g_hash_table_size (ptr_tracker) == 0) {
+			g_print ("   All tracked pointers were properly removed\n");
+		} 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) {
+		g_print ("\n----------------------------------------------------------\n");
+		g_print ("   Did not track any pointers yet\n");
+		g_print ("----------------------------------------------------------\n");
+	}
+
+	G_UNLOCK (ptr_tracker);
+}
+
+#ifdef HAVE_BACKTRACE_SYMBOLS
+
+#ifdef HAVE_ELFUTILS_LIBDWFL
+static Dwfl *
+dwfl_get (gboolean reload)
+{
+	static gchar *debuginfo_path = NULL;
+	static Dwfl *dwfl = NULL;
+	static gboolean checked_for_dwfl = FALSE;
+	static GStaticMutex dwfl_mutex = G_STATIC_MUTEX_INIT;
+	static const Dwfl_Callbacks proc_callbacks = {
+		.find_debuginfo = dwfl_standard_find_debuginfo,
+		.debuginfo_path = &debuginfo_path,
+		.find_elf = dwfl_linux_proc_find_elf
+	};
+
+	g_static_mutex_lock (&dwfl_mutex);
+
+	if (checked_for_dwfl) {
+		if (!reload) {
+			g_static_mutex_unlock (&dwfl_mutex);
+			return dwfl;
+		}
+
+		dwfl_end (dwfl);
+		dwfl = NULL;
+	}
+
+	checked_for_dwfl = TRUE;
+
+	dwfl = dwfl_begin (&proc_callbacks);
+	if (!dwfl) {
+		g_static_mutex_unlock (&dwfl_mutex);
+		return NULL;
+	}
+
+	errno = 0;
+	if (dwfl_linux_proc_report (dwfl, getpid ()) != 0 || dwfl_report_end (dwfl, NULL, NULL) != 0) {
+		dwfl_end (dwfl);
+		dwfl = NULL;
+	}
+
+	g_static_mutex_unlock (&dwfl_mutex);
+
+	return dwfl;
+}
+
+struct getmodules_callback_arg
+{
+	gpointer addr;
+	const gchar *func_name;
+	const gchar *file_path;
+	gint lineno;
+};
+
+static gint
+getmodules_callback (Dwfl_Module *module,
+                     gpointer *module_userdata_pointer,
+                     const gchar *module_name,
+                     Dwarf_Addr module_low_addr,
+                     gpointer arg_voidp)
+{
+	struct getmodules_callback_arg *arg = arg_voidp;
+	Dwfl_Line *line;
+
+	arg->func_name = dwfl_module_addrname (module, (GElf_Addr) arg->addr);
+	line = dwfl_module_getsrc (module, (GElf_Addr) arg->addr);
+	if (line) {
+		arg->file_path = dwfl_lineinfo (line, NULL, &arg->lineno, NULL, NULL, NULL);
+	} else {
+		arg->file_path = NULL;
+	}
+
+	return arg->func_name ? DWARF_CB_ABORT : DWARF_CB_OK;
+}
+#endif /* HAVE_ELFUTILS_LIBDWFL */
+
+static const gchar *
+addr_lookup (gpointer addr,
+             const gchar **file_path,
+             gint *lineno,
+             const gchar *fallback)
+{
+#ifdef HAVE_ELFUTILS_LIBDWFL
+	Dwfl *dwfl = dwfl_get (FALSE);
+	struct getmodules_callback_arg arg;
+
+	if (!dwfl)
+		return NULL;
+
+	arg.addr = addr;
+	arg.func_name = NULL;
+	arg.file_path = NULL;
+	arg.lineno = -1;
+
+	dwfl_getmodules (dwfl, getmodules_callback, &arg, 0);
+
+	if (!arg.func_name && fallback && strstr (fallback, "/lib") != fallback && strstr (fallback, "/usr/lib") != fallback) {
+		dwfl = dwfl_get (TRUE);
+		if (dwfl)
+			dwfl_getmodules (dwfl, getmodules_callback, &arg, 0);
+	}
+
+	*file_path = arg.file_path;
+	*lineno = arg.lineno;
+
+	return arg.func_name;
+#else /* HAVE_ELFUTILS_LIBDWFL */
+	return NULL;
+#endif /* HAVE_ELFUTILS_LIBDWFL */
+}
+
+#endif /* HAVE_BACKTRACE_SYMBOLS */
+
+static GString *
+get_current_backtrace (void)
+{
+#ifdef HAVE_BACKTRACE_SYMBOLS
+	#define MAX_BT_DEPTH 50
+	gint nptrs, ii;
+	gpointer bt[MAX_BT_DEPTH + 1];
+	gchar **bt_syms;
+	GString *bt_str;
+
+	nptrs = backtrace (bt, MAX_BT_DEPTH + 1);
+	if (nptrs <= 2)
+		return NULL;
+
+	bt_syms = backtrace_symbols (bt, nptrs);
+	if (!bt_syms)
+		return NULL;
+
+	bt_str = g_string_new ("");
+	for (ii = 2; ii < nptrs; ii++) {
+		gint lineno = -1;
+		const gchar *file_path = NULL;
+		const gchar *str = addr_lookup (bt[ii], &file_path, &lineno, bt_syms[ii]);
+		if (!str) {
+			str = bt_syms[ii];
+			file_path = NULL;
+			lineno = -1;
+		}
+		if (!str)
+			continue;
+
+		if (bt_str->len)
+			g_string_append (bt_str, "\n\t   by ");
+		g_string_append (bt_str, str);
+		if (str != bt_syms[ii])
+			g_string_append (bt_str, "()");
+
+		if (file_path && lineno > 0) {
+			const gchar *lastsep = strrchr (file_path, G_DIR_SEPARATOR);
+			g_string_append_printf (bt_str, " at %s:%d", lastsep ? lastsep + 1 : file_path, lineno);
+		}
+	}
+
+	g_free (bt_syms);
+
+	if (bt_str->len == 0) {
+		g_string_free (bt_str, TRUE);
+		bt_str = NULL;
+	} else {
+		g_string_insert (bt_str, 0, "\t   at ");
+	}
+
+	return bt_str;
+
+	#undef MAX_BT_DEPTH
+#else /* HAVE_BACKTRACE_SYMBOLS */
+	return NULL;
+#endif /* HAVE_BACKTRACE_SYMBOLS */
+}
+
+static void
+dump_left_at_exit_cb (void)
+{
+	dump_tracked_ptrs (TRUE);
+
+	G_LOCK (ptr_tracker);
+	if (ptr_tracker) {
+		g_hash_table_destroy (ptr_tracker);
+		ptr_tracker = NULL;
+	}
+	G_UNLOCK (ptr_tracker);
+}
+
+/**
+ * camel_pointer_tracker_track_with_info:
+ * @ptr: pointer to add to the pointer tracker
+ * @info: info to print in tracker summary
+ *
+ * Adds pointer to the pointer tracker, with associated information,
+ * which is printed in summary of pointer tracker printed by
+ * camel_pointer_tracker_dump(). For convenience can be used
+ * camel_pointer_tracker_track(), which adds place of the caller
+ * as @info. Added pointer should be removed with pair function
+ * camel_pointer_tracker_untrack().
+ *
+ * Since: 3.6
+ **/
+void
+camel_pointer_tracker_track_with_info (gpointer ptr,
+				       const gchar *info)
+{
+	struct pt_data *ptd;
+
+	g_return_if_fail (ptr != NULL);
+
+	G_LOCK (ptr_tracker);
+	if (!ptr_tracker) {
+		ptr_tracker = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, free_pt_data);
+		g_atexit (dump_left_at_exit_cb);
+	}
+
+	ptd = g_new0 (struct pt_data, 1);
+	ptd->ptr = ptr;
+	ptd->info = g_strdup (info);
+	ptd->backtrace = get_current_backtrace ();
+
+	g_hash_table_insert (ptr_tracker, ptr, ptd);
+
+	G_UNLOCK (ptr_tracker);
+}
+
+/**
+ * camel_pointer_tracker_untrack:
+ * @ptr: pointer to remove from the tracker
+ *
+ * Removes pointer from the pointer tracker. It's an error to try
+ * to remove pointer which was not added to the tracker by
+ * camel_pointer_tracker_track() or camel_pointer_tracker_track_with_info(),
+ * or a pointer which was already removed.
+ *
+ * Since: 3.6
+ **/
+void
+camel_pointer_tracker_untrack (gpointer ptr)
+{
+	g_return_if_fail (ptr != NULL);
+
+	G_LOCK (ptr_tracker);
+
+	if (!ptr_tracker)
+		g_printerr ("Pointer tracker not initialized, thus cannot remove %p\n", ptr);
+	else if (!g_hash_table_lookup (ptr_tracker, ptr))
+		g_printerr ("Pointer %p is not tracked\n", ptr);
+	else
+		g_hash_table_remove (ptr_tracker, ptr);
+
+	G_UNLOCK (ptr_tracker);
+}
+
+/**
+ * camel_pointer_tracker_dump:
+ *
+ * Prints information about currently stored pointers
+ * in the pointer tracker. This is called automatically
+ * on application exit if camel_pointer_tracker_track() or
+ * camel_pointer_tracker_track_with_info() was called.
+ *
+ * Note: If the library is configured with --enable-backtraces,
+ * then also backtraces where the pointer was added is printed
+ * in the summary.
+ *
+ * Since: 3.6
+ **/
+void
+camel_pointer_tracker_dump (void)
+{
+	dump_tracked_ptrs (FALSE);
+}
diff --git a/camel/camel-debug.h b/camel/camel-debug.h
index c85bbcf..4bb097a 100644
--- a/camel/camel-debug.h
+++ b/camel/camel-debug.h
@@ -79,6 +79,29 @@ void camel_debug_end (void);
 	} \
 	} G_STMT_END
 
+/**
+ * camel_pointer_tracker_track:
+ * @ptr: pointer to add to pointer tracker
+ *
+ * Adds pointer 'ptr' to pointer tracker. Usual use case is to add object
+ * to the tracker in GObject::init and remove it from tracker within
+ * GObject::finalize. Since the tracker's functions are called, the application
+ * prints summary of the pointers on console on exit. If everything gone right
+ * then it prints message about all tracked pointers were removed. Otherwise
+ * it prints summary of left pointers in the tracker. Added pointer should
+ * be removed with pair function camel_pointer_tracker_untrack().
+ *
+ * See camel_pointer_tracker_dump(), camel_pointer_tracker_track_with_info().
+ *
+ * Since: 3.6
+ **/
+#define camel_pointer_tracker_track(ptr) \
+	(camel_pointer_tracker_track_with_info ((ptr), G_STRFUNC))
+
+void		camel_pointer_tracker_track_with_info (gpointer ptr, const gchar *info);
+void		camel_pointer_tracker_untrack (gpointer ptr);
+void		camel_pointer_tracker_dump (void);
+
 G_END_DECLS
 
 #endif /* CAMEL_DEBUG_H */
diff --git a/configure.ac b/configure.ac
index cee40b3..a55a5d0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -558,7 +558,7 @@ LIBS="$save_LIBS"
 
 AC_ARG_ENABLE([backtraces],
 	[AS_HELP_STRING([--enable-backtraces],
-	[enable backtraces for e_pointer_tracker (default=no)])],
+	[enable backtraces for camel_pointer_tracker (default=no)])],
 	[enable_backtraces=$enableval], [enable_backtraces=no])
 
 if test "x$enable_backtraces" = xyes; then
diff --git a/libedataserver/Makefile.am b/libedataserver/Makefile.am
index 4c0d9e5..72f689a 100644
--- a/libedataserver/Makefile.am
+++ b/libedataserver/Makefile.am
@@ -105,8 +105,7 @@ libedataserver_1_2_la_LIBADD =				\
 	$(GIO_UNIX_LIBS)				\
 	$(ICONV_LIBS)					\
 	$(SOCKET_LIBS)					\
-	$(SOUP_LIBS)					\
-	$(LIBDWFL_LIBS)
+	$(SOUP_LIBS)
 
 libedataserver_1_2_la_LDFLAGS = \
 	-version-info $(LIBEDATASERVER_CURRENT):$(LIBEDATASERVER_REVISION):$(LIBEDATASERVER_AGE) $(NO_UNDEFINED) \
diff --git a/libedataserver/e-data-server-util.c b/libedataserver/e-data-server-util.c
index e18831d..3aca9e8 100644
--- a/libedataserver/e-data-server-util.c
+++ b/libedataserver/e-data-server-util.c
@@ -26,14 +26,6 @@
 #include <time.h>
 #include <unistd.h>
 
-#ifdef HAVE_BACKTRACE_SYMBOLS
-#include <execinfo.h>
-#ifdef HAVE_ELFUTILS_LIBDWFL
-#include <elfutils/libdwfl.h>
-#include <errno.h>
-#endif
-#endif
-
 #ifdef G_OS_WIN32
 #include <mbstring.h>
 #endif
@@ -1548,397 +1540,3 @@ e_data_server_util_get_dbus_call_timeout (void)
 {
 	return default_dbus_timeout;
 }
-
-G_LOCK_DEFINE_STATIC (ptr_tracker);
-static GHashTable *ptr_tracker = NULL;
-
-struct pt_data {
-	gpointer ptr;
-	gchar *info;
-	GString *backtrace;
-};
-
-static void
-free_pt_data (gpointer ptr)
-{
-	struct pt_data *ptd = ptr;
-
-	if (!ptd)
-		return;
-
-	g_free (ptd->info);
-	if (ptd->backtrace)
-		g_string_free (ptd->backtrace, TRUE);
-	g_free (ptd);
-}
-
-static void
-dump_left_ptrs_cb (gpointer key,
-                   gpointer value,
-                   gpointer user_data)
-{
-	guint *left = user_data;
-	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", 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)
-{
-	G_LOCK (ptr_tracker);
-
-	if (ptr_tracker) {
-		g_print ("\n----------------------------------------------------------\n");
-		if (g_hash_table_size (ptr_tracker) == 0) {
-			g_print ("   All tracked pointers were properly removed\n");
-		} 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) {
-		g_print ("\n----------------------------------------------------------\n");
-		g_print ("   Did not track any pointers yet\n");
-		g_print ("----------------------------------------------------------\n");
-	}
-
-	G_UNLOCK (ptr_tracker);
-}
-
-#ifdef HAVE_BACKTRACE_SYMBOLS
-
-#ifdef HAVE_ELFUTILS_LIBDWFL
-static Dwfl *
-dwfl_get (gboolean reload)
-{
-	static gchar *debuginfo_path = NULL;
-	static Dwfl *dwfl = NULL;
-	static gboolean checked_for_dwfl = FALSE;
-	static GStaticMutex dwfl_mutex = G_STATIC_MUTEX_INIT;
-	static const Dwfl_Callbacks proc_callbacks = {
-		.find_debuginfo = dwfl_standard_find_debuginfo,
-		.debuginfo_path = &debuginfo_path,
-		.find_elf = dwfl_linux_proc_find_elf
-	};
-
-	g_static_mutex_lock (&dwfl_mutex);
-
-	if (checked_for_dwfl) {
-		if (!reload) {
-			g_static_mutex_unlock (&dwfl_mutex);
-			return dwfl;
-		}
-
-		dwfl_end (dwfl);
-		dwfl = NULL;
-	}
-
-	checked_for_dwfl = TRUE;
-
-	dwfl = dwfl_begin (&proc_callbacks);
-	if (!dwfl) {
-		g_static_mutex_unlock (&dwfl_mutex);
-		return NULL;
-	}
-
-	errno = 0;
-	if (dwfl_linux_proc_report (dwfl, getpid ()) != 0 || dwfl_report_end (dwfl, NULL, NULL) != 0) {
-		dwfl_end (dwfl);
-		dwfl = NULL;
-	}
-
-	g_static_mutex_unlock (&dwfl_mutex);
-
-	return dwfl;
-}
-
-struct getmodules_callback_arg
-{
-	gpointer addr;
-	const gchar *func_name;
-	const gchar *file_path;
-	gint lineno;
-};
-
-static gint
-getmodules_callback (Dwfl_Module *module,
-                     gpointer *module_userdata_pointer,
-                     const gchar *module_name,
-                     Dwarf_Addr module_low_addr,
-                     gpointer arg_voidp)
-{
-	struct getmodules_callback_arg *arg = arg_voidp;
-	Dwfl_Line *line;
-
-	arg->func_name = dwfl_module_addrname (module, (GElf_Addr) arg->addr);
-	line = dwfl_module_getsrc (module, (GElf_Addr) arg->addr);
-	if (line) {
-		arg->file_path = dwfl_lineinfo (line, NULL, &arg->lineno, NULL, NULL, NULL);
-	} else {
-		arg->file_path = NULL;
-	}
-
-	return arg->func_name ? DWARF_CB_ABORT : DWARF_CB_OK;
-}
-#endif /* HAVE_ELFUTILS_LIBDWFL */
-
-static const gchar *
-addr_lookup (gpointer addr,
-             const gchar **file_path,
-             gint *lineno,
-             const gchar *fallback)
-{
-#ifdef HAVE_ELFUTILS_LIBDWFL
-	Dwfl *dwfl = dwfl_get (FALSE);
-	struct getmodules_callback_arg arg;
-
-	if (!dwfl)
-		return NULL;
-
-	arg.addr = addr;
-	arg.func_name = NULL;
-	arg.file_path = NULL;
-	arg.lineno = -1;
-
-	dwfl_getmodules (dwfl, getmodules_callback, &arg, 0);
-
-	if (!arg.func_name && fallback && strstr (fallback, "/lib") != fallback && strstr (fallback, "/usr/lib") != fallback) {
-		dwfl = dwfl_get (TRUE);
-		if (dwfl)
-			dwfl_getmodules (dwfl, getmodules_callback, &arg, 0);
-	}
-
-	*file_path = arg.file_path;
-	*lineno = arg.lineno;
-
-	return arg.func_name;
-#else /* HAVE_ELFUTILS_LIBDWFL */
-	return NULL;
-#endif /* HAVE_ELFUTILS_LIBDWFL */
-}
-
-#endif /* HAVE_BACKTRACE_SYMBOLS */
-
-static GString *
-get_current_backtrace (void)
-{
-#ifdef HAVE_BACKTRACE_SYMBOLS
-	#define MAX_BT_DEPTH 50
-	gint nptrs, ii;
-	gpointer bt[MAX_BT_DEPTH + 1];
-	gchar **bt_syms;
-	GString *bt_str;
-
-	nptrs = backtrace (bt, MAX_BT_DEPTH + 1);
-	if (nptrs <= 2)
-		return NULL;
-
-	bt_syms = backtrace_symbols (bt, nptrs);
-	if (!bt_syms)
-		return NULL;
-
-	bt_str = g_string_new ("");
-	for (ii = 2; ii < nptrs; ii++) {
-		gint lineno = -1;
-		const gchar *file_path = NULL;
-		const gchar *str = addr_lookup (bt[ii], &file_path, &lineno, bt_syms[ii]);
-		if (!str) {
-			str = bt_syms[ii];
-			file_path = NULL;
-			lineno = -1;
-		}
-		if (!str)
-			continue;
-
-		if (bt_str->len)
-			g_string_append (bt_str, "\n\t   by ");
-		g_string_append (bt_str, str);
-		if (str != bt_syms[ii])
-			g_string_append (bt_str, "()");
-
-		if (file_path && lineno > 0) {
-			const gchar *lastsep = strrchr (file_path, G_DIR_SEPARATOR);
-			g_string_append_printf (bt_str, " at %s:%d", lastsep ? lastsep + 1 : file_path, lineno);
-		}
-	}
-
-	g_free (bt_syms);
-
-	if (bt_str->len == 0) {
-		g_string_free (bt_str, TRUE);
-		bt_str = NULL;
-	} else {
-		g_string_insert (bt_str, 0, "\t   at ");
-	}
-
-	return bt_str;
-
-	#undef MAX_BT_DEPTH
-#else /* HAVE_BACKTRACE_SYMBOLS */
-	return NULL;
-#endif /* HAVE_BACKTRACE_SYMBOLS */
-}
-
-static void
-dump_left_at_exit_cb (void)
-{
-	dump_tracked_ptrs (TRUE);
-
-	G_LOCK (ptr_tracker);
-	if (ptr_tracker) {
-		g_hash_table_destroy (ptr_tracker);
-		ptr_tracker = NULL;
-	}
-	G_UNLOCK (ptr_tracker);
-}
-
-/**
- * e_pointer_tracker_track_with_info:
- *
- * FIXME: Document me.
- *
- * Since: 3.2
- **/
-void
-e_pointer_tracker_track_with_info (gpointer ptr,
-                                   const gchar *info)
-{
-	struct pt_data *ptd;
-
-	g_return_if_fail (ptr != NULL);
-
-	G_LOCK (ptr_tracker);
-	if (!ptr_tracker) {
-		ptr_tracker = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, free_pt_data);
-		g_atexit (dump_left_at_exit_cb);
-	}
-
-	ptd = g_new0 (struct pt_data, 1);
-	ptd->ptr = ptr;
-	ptd->info = g_strdup (info);
-	ptd->backtrace = get_current_backtrace ();
-
-	g_hash_table_insert (ptr_tracker, ptr, ptd);
-
-	G_UNLOCK (ptr_tracker);
-}
-
-/**
- * e_pointer_tracker_untrack:
- *
- * FIXME: Document me.
- *
- * Since: 3.2
- **/
-void
-e_pointer_tracker_untrack (gpointer ptr)
-{
-	g_return_if_fail (ptr != NULL);
-
-	G_LOCK (ptr_tracker);
-
-	if (!ptr_tracker)
-		g_printerr ("Pointer tracker not initialized, thus cannot remove %p\n", ptr);
-	else if (!g_hash_table_lookup (ptr_tracker, ptr))
-		g_printerr ("Pointer %p is not tracked\n", ptr);
-	else
-		g_hash_table_remove (ptr_tracker, ptr);
-
-	G_UNLOCK (ptr_tracker);
-}
-
-/**
- * e_pointer_tracker_dump:
- *
- * FIXME: Document me.
- *
- * Since: 3.2
- **/
-void
-e_pointer_tracker_dump (void)
-{
-	dump_tracked_ptrs (FALSE);
-}
diff --git a/libedataserver/e-data-server-util.h b/libedataserver/e-data-server-util.h
index 371a415..24e26a1 100644
--- a/libedataserver/e-data-server-util.h
+++ b/libedataserver/e-data-server-util.h
@@ -123,20 +123,6 @@ gint		e_data_server_util_get_dbus_call_timeout
 void		e_data_server_util_set_dbus_call_timeout
 						(gint timeout_msec);
 
-/**
- * e_pointer_tracker_track:
- *
- * FIXME: Document me.
- *
- * Since: 3.2
- **/
-#define e_pointer_tracker_track(ptr) \
-	(e_pointer_tracker_track_with_info ((ptr), G_STRFUNC))
-
-void		e_pointer_tracker_track_with_info (gpointer ptr, const gchar *info);
-void		e_pointer_tracker_untrack (gpointer ptr);
-void		e_pointer_tracker_dump (void);
-
 G_END_DECLS
 
 #endif /* E_DATA_SERVER_UTIL_H */



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