Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/lib/ev-debug.c
diff options
context:
space:
mode:
authorMarco Pesenti Gritti <marco@gnome.org>2005-02-07 21:11:11 (GMT)
committer Marco Pesenti Gritti <marco@src.gnome.org>2005-02-07 21:11:11 (GMT)
commit16ebda50ec3b3ab96d9bbc3c8e8522b269ef1191 (patch)
tree9ce47e72252a664162bf858188190b26114a737e /lib/ev-debug.c
parentc27987b5463e16a8a860e643db2091bbb1ce1628 (diff)
Add debugging helpers
2005-02-07 Marco Pesenti Gritti <marco@gnome.org> * Makefile.am: * configure.ac: * doc/debugging.txt: * lib/.cvsignore: * lib/Makefile.am: * lib/ev-debug.c: (log_module), (trap_handler), (ev_debug_init), (ev_profiler_new), (ev_should_profile), (ev_profiler_dump), (ev_profiler_free), (ev_profiler_start), (ev_profiler_stop): * lib/ev-debug.h: Add debugging helpers * ps/Makefile.am: * ps/ps-document.c: (set_up_page), (start_interpreter), (stop_interpreter), (document_load), (ps_document_next_page), (ps_document_goto_page), (ps_document_set_page_size), (ps_document_widget_event), (ps_document_render): * shell/Makefile.am: * shell/ev-view.c: (expose_bin_window): * shell/main.c: (main): Add some logs
Diffstat (limited to 'lib/ev-debug.c')
-rw-r--r--lib/ev-debug.c239
1 files changed, 239 insertions, 0 deletions
diff --git a/lib/ev-debug.c b/lib/ev-debug.c
new file mode 100644
index 0000000..8648e2d
--- /dev/null
+++ b/lib/ev-debug.c
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2003 Marco Pesenti Gritti
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+
+#include "config.h"
+
+#include "ev-debug.h"
+
+#ifndef DISABLE_PROFILING
+
+#include <glib/gbacktrace.h>
+#include <string.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <execinfo.h>
+
+static GHashTable *ev_profilers_hash = NULL;
+static const char *ev_profile_modules = NULL;
+static const char *ev_debug_break = NULL;
+
+#endif
+
+#ifndef DISABLE_LOGGING
+
+static const char *ev_log_modules;
+
+static void
+log_module (const gchar *log_domain,
+ GLogLevelFlags log_level,
+ const gchar *message,
+ gpointer user_data)
+{
+ gboolean should_log = FALSE;
+
+ if (!ev_log_modules) return;
+
+ if (strcmp (ev_log_modules, "all") != 0)
+ {
+ char **modules;
+ int i;
+
+ modules = g_strsplit (ev_log_modules, ":", 100);
+
+ for (i = 0; modules[i] != NULL; i++)
+ {
+ if (strstr (message, modules [i]) != NULL)
+ {
+ should_log = TRUE;
+ break;
+ }
+ }
+
+ g_strfreev (modules);
+ }
+ else
+ {
+ should_log = TRUE;
+ }
+
+ if (should_log)
+ {
+ g_print ("%s\n", message);
+ }
+}
+
+#define MAX_DEPTH 200
+
+static void
+trap_handler (const char *log_domain,
+ GLogLevelFlags log_level,
+ const char *message,
+ gpointer user_data)
+{
+ g_log_default_handler (log_domain, log_level, message, user_data);
+
+ if (ev_debug_break != NULL &&
+ (log_level & (G_LOG_LEVEL_WARNING |
+ G_LOG_LEVEL_ERROR |
+ G_LOG_LEVEL_CRITICAL |
+ G_LOG_FLAG_FATAL)))
+ {
+ if (strcmp (ev_debug_break, "stack") == 0)
+ {
+ void *array[MAX_DEPTH];
+ size_t size;
+
+ size = backtrace (array, MAX_DEPTH);
+ backtrace_symbols_fd (array, size, 2);
+ }
+ else if (strcmp (ev_debug_break, "trap") == 0)
+ {
+ G_BREAKPOINT ();
+ }
+ else if (strcmp (ev_debug_break, "suspend") == 0)
+ {
+ g_print ("Suspending program; attach with the debugger.\n");
+
+ raise (SIGSTOP);
+ }
+ }
+}
+
+#endif
+
+void
+ev_debug_init (void)
+{
+#ifndef DISABLE_LOGGING
+ ev_log_modules = g_getenv ("EV_LOG_MODULES");
+ ev_debug_break = g_getenv ("EV_DEBUG_BREAK");
+
+ g_log_set_default_handler (trap_handler, NULL);
+
+ g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, log_module, NULL);
+
+#endif
+#ifndef DISABLE_PROFILING
+ ev_profile_modules = g_getenv ("EV_PROFILE_MODULES");
+#endif
+}
+
+#ifndef DISABLE_PROFILING
+
+static EvProfiler *
+ev_profiler_new (const char *name, const char *module)
+{
+ EvProfiler *profiler;
+
+ profiler = g_new0 (EvProfiler, 1);
+ profiler->timer = g_timer_new ();
+ profiler->name = g_strdup (name);
+ profiler->module = g_strdup (module);
+
+ g_timer_start (profiler->timer);
+
+ return profiler;
+}
+
+static gboolean
+ev_should_profile (const char *module)
+{
+ char **modules;
+ int i;
+ gboolean res = FALSE;
+
+ if (!ev_profile_modules) return FALSE;
+ if (strcmp (ev_profile_modules, "all") == 0) return TRUE;
+
+ modules = g_strsplit (ev_profile_modules, ":", 100);
+
+ for (i = 0; modules[i] != NULL; i++)
+ {
+ if (strcmp (module, modules [i]) == 0)
+ {
+ res = TRUE;
+ break;
+ }
+ }
+
+ g_strfreev (modules);
+
+ return res;
+}
+
+static void
+ev_profiler_dump (EvProfiler *profiler)
+{
+ double seconds;
+
+ g_return_if_fail (profiler != NULL);
+
+ seconds = g_timer_elapsed (profiler->timer, NULL);
+
+ g_print ("[ %s ] %s %f s elapsed\n",
+ profiler->module, profiler->name,
+ seconds);
+}
+
+static void
+ev_profiler_free (EvProfiler *profiler)
+{
+ g_return_if_fail (profiler != NULL);
+
+ g_timer_destroy (profiler->timer);
+ g_free (profiler->name);
+ g_free (profiler->module);
+ g_free (profiler);
+}
+
+void
+ev_profiler_start (const char *name, const char *module)
+{
+ EvProfiler *profiler;
+
+ if (ev_profilers_hash == NULL)
+ {
+ ev_profilers_hash =
+ g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, NULL);
+ }
+
+ if (!ev_should_profile (module)) return;
+
+ profiler = ev_profiler_new (name, module);
+
+ g_hash_table_insert (ev_profilers_hash, g_strdup (name), profiler);
+}
+
+void
+ev_profiler_stop (const char *name)
+{
+ EvProfiler *profiler;
+
+ profiler = g_hash_table_lookup (ev_profilers_hash, name);
+ if (profiler == NULL) return;
+ g_hash_table_remove (ev_profilers_hash, name);
+
+ ev_profiler_dump (profiler);
+ ev_profiler_free (profiler);
+}
+
+#endif