[Xfce4-commits] <xfce4-panel:master> Add support to run plugins in valgrind.
Nick Schermer
noreply at xfce.org
Sat Jul 17 15:32:01 CEST 2010
Updating branch refs/heads/master
to ce1960aec559a1e6c3dc97dd1919234e79d0e279 (commit)
from f10c0061e6cc72d7af8b1ff0dd5174aa92b414ed (commit)
commit ce1960aec559a1e6c3dc97dd1919234e79d0e279
Author: Nick Schermer <nick at xfce.org>
Date: Sat Jul 17 15:29:44 2010 +0200
Add support to run plugins in valgrind.
Also set the environment variables G_SLICE and G_DEBUG for
better debugging or checking for memory leaks.
common/panel-debug.c | 37 ++++++++++++---
common/panel-debug.h | 5 +-
panel/panel-plugin-external.c | 102 +++++++++++++++++++++++++----------------
3 files changed, 95 insertions(+), 49 deletions(-)
diff --git a/common/panel-debug.c b/common/panel-debug.c
index b99e8cb..8083cc9 100644
--- a/common/panel-debug.c
+++ b/common/panel-debug.c
@@ -37,7 +37,8 @@ PanelDebugFlag panel_debug_flags = 0;
/* additional debug levels */
static const GDebugKey panel_debug_keys[] =
{
- { "gdb", PANEL_DEBUG_GDB }
+ { "gdb", PANEL_DEBUG_GDB },
+ { "valgrind", PANEL_DEBUG_VALGRIND }
};
@@ -51,6 +52,7 @@ panel_debug (const gchar *domain,
const gchar *value;
gchar *string, *path;
va_list args;
+ const gchar *proxy_application;
panel_return_if_fail (domain != NULL);
panel_return_if_fail (message != NULL);
@@ -59,7 +61,7 @@ panel_debug (const gchar *domain,
if (g_once_init_enter (&level__volatile))
{
value = g_getenv ("PANEL_DEBUG");
- if (G_UNLIKELY (value != NULL))
+ if (value != NULL && *value != '\0')
{
panel_debug_flags = g_parse_debug_string (value, panel_debug_keys,
G_N_ELEMENTS (panel_debug_keys));
@@ -67,21 +69,42 @@ panel_debug (const gchar *domain,
/* always enable debug logging */
PANEL_SET_FLAG (panel_debug_flags, PANEL_DEBUG_YES);
- /* TODO: only print this in the main application */
if (PANEL_HAS_FLAG (panel_debug_flags, PANEL_DEBUG_GDB))
{
- path = g_find_program_in_path ("gdb");
+ proxy_application = "gdb";
+
+ /* performs sanity checks on the released memory slices */
+ g_setenv ("G_SLICE", "debug-blocks", TRUE);
+ }
+ else if (PANEL_HAS_FLAG (panel_debug_flags, PANEL_DEBUG_VALGRIND))
+ {
+ proxy_application = "valgrind";
+
+ /* use g_malloc() and g_free() instead of slices */
+ g_setenv ("G_SLICE", "always-malloc", TRUE);
+ g_setenv ("G_DEBUG", "gc-friendly", TRUE);
+ }
+ else
+ {
+ proxy_application = NULL;
+ }
+
+ if (proxy_application != NULL)
+ {
+ path = g_find_program_in_path (proxy_application);
if (G_LIKELY (path != NULL))
{
+ /* TODO: only print those messages in the main application */
g_printerr (PACKAGE_NAME "(debug): running plugins with %s; "
- "log files stored in '%s'\n", path, g_get_tmp_dir ());
+ "log files stored in %s\n", path, g_get_tmp_dir ());
g_free (path);
}
else
{
- PANEL_UNSET_FLAG (panel_debug_flags, PANEL_DEBUG_GDB);
+ PANEL_UNSET_FLAG (panel_debug_flags, PANEL_DEBUG_GDB | PANEL_DEBUG_VALGRIND);
- g_printerr (PACKAGE_NAME "(debug): gdb not found in PATH; mode disabled\n");
+ g_printerr (PACKAGE_NAME "(debug): %s not found in PATH\n",
+ proxy_application);
}
}
}
diff --git a/common/panel-debug.h b/common/panel-debug.h
index 200758f..d7e7b71 100644
--- a/common/panel-debug.h
+++ b/common/panel-debug.h
@@ -32,8 +32,9 @@
typedef enum
{
- PANEL_DEBUG_YES = 1 << 0, /* always enabled if PANEL_DEBUG is not %NULL */
- PANEL_DEBUG_GDB = 1 << 1 /* run plugin through gdb */
+ PANEL_DEBUG_YES = 1 << 0, /* always enabled if PANEL_DEBUG is not %NULL */
+ PANEL_DEBUG_GDB = 1 << 1, /* run plugin in gdb */
+ PANEL_DEBUG_VALGRIND = 1 << 2 /* run plugin in valgrind */
}
PanelDebugFlag;
diff --git a/panel/panel-plugin-external.c b/panel/panel-plugin-external.c
index 27bc003..9266220 100644
--- a/panel/panel-plugin-external.c
+++ b/panel/panel-plugin-external.c
@@ -488,7 +488,7 @@ panel_plugin_external_child_spawn (PanelPluginExternal *external)
GError *error = NULL;
gboolean succeed;
GPid pid;
- gchar *gdb, *cmd_line;
+ gchar *program, *cmd_line;
guint i;
gint tmp_argc;
GTimeVal timestamp;
@@ -501,53 +501,75 @@ panel_plugin_external_child_spawn (PanelPluginExternal *external)
panel_return_if_fail (argv != NULL);
/* check debugging state */
- if (G_UNLIKELY (PANEL_HAS_FLAG (panel_debug_flags, PANEL_DEBUG_GDB)))
+ if (PANEL_HAS_FLAG (panel_debug_flags, PANEL_DEBUG_GDB)
+ || PANEL_HAS_FLAG (panel_debug_flags, PANEL_DEBUG_VALGRIND))
{
- gdb = g_find_program_in_path ("gdb");
- if (G_LIKELY (gdb != NULL))
+ g_get_current_time (×tamp);
+ cmd_line = NULL;
+ program = NULL;
+
+ if (PANEL_HAS_FLAG (panel_debug_flags, PANEL_DEBUG_GDB))
{
- g_get_current_time (×tamp);
- cmd_line = g_strdup_printf ("%s -batch "
- "-ex 'set logging file %s" G_DIR_SEPARATOR_S "%li-%s-%s.txt' "
- "-ex 'set logging on' "
- "-ex 'set pagination off' "
- "-ex 'set logging redirect on' "
- "-ex 'run' "
- "-ex 'backtrace full' "
- "-ex 'info registers' "
- "-args",
- gdb, g_get_tmp_dir (), timestamp.tv_sec,
- panel_module_get_name (external->module),
- argv[PLUGIN_ARGV_UNIQUE_ID]);
-
- if (g_shell_parse_argv (cmd_line, &tmp_argc, &tmp_argv, &error))
+ program = g_find_program_in_path ("gdb");
+ if (G_LIKELY (program != NULL))
{
- dbg_argv = g_new0 (gchar *, tmp_argc + g_strv_length (argv) + 1);
-
- for (i = 0; tmp_argv[i] != NULL; i++)
- dbg_argv[i] = tmp_argv[i];
- g_free (tmp_argv);
-
- for (i = 0; argv[i] != NULL; i++)
- dbg_argv[i + tmp_argc] = argv[i];
- g_free (argv);
-
- argv = dbg_argv;
+ cmd_line = g_strdup_printf ("%s -batch "
+ "-ex 'set logging file %s" G_DIR_SEPARATOR_S "%li_gdb_%s_%s.log' "
+ "-ex 'set logging on' "
+ "-ex 'set pagination off' "
+ "-ex 'set logging redirect on' "
+ "-ex 'run' "
+ "-ex 'backtrace full' "
+ "-ex 'info registers' "
+ "-args",
+ program, g_get_tmp_dir (), timestamp.tv_sec,
+ panel_module_get_name (external->module),
+ argv[PLUGIN_ARGV_UNIQUE_ID]);
}
- else
+ }
+ else if (PANEL_HAS_FLAG (panel_debug_flags, PANEL_DEBUG_VALGRIND))
+ {
+ program = g_find_program_in_path ("valgrind");
+ if (G_LIKELY (program != NULL))
{
- panel_debug (PANEL_DEBUG_DOMAIN_EXTERNAL,
- "%s-%d: Failed to parse the gdb command line: %s",
- panel_module_get_name (external->module),
- external->unique_id, error->message);
- g_error_free (error);
-
- return;
+ cmd_line = g_strdup_printf ("%s "
+ "--log-file='%s" G_DIR_SEPARATOR_S "%li_valgrind_%s_%s.log' "
+ "--leak-check=full --show-reachable=yes -v ",
+ program, g_get_tmp_dir (), timestamp.tv_sec,
+ panel_module_get_name (external->module),
+ argv[PLUGIN_ARGV_UNIQUE_ID]);
}
+ }
- g_free (gdb);
- g_free (cmd_line);
+ if (cmd_line != NULL
+ && g_shell_parse_argv (cmd_line, &tmp_argc, &tmp_argv, &error))
+ {
+ dbg_argv = g_new0 (gchar *, tmp_argc + g_strv_length (argv) + 1);
+
+ for (i = 0; tmp_argv[i] != NULL; i++)
+ dbg_argv[i] = tmp_argv[i];
+ g_free (tmp_argv);
+
+ for (i = 0; argv[i] != NULL; i++)
+ dbg_argv[i + tmp_argc] = argv[i];
+ g_free (argv);
+
+ argv = dbg_argv;
}
+ else
+ {
+ panel_debug (PANEL_DEBUG_DOMAIN_EXTERNAL,
+ "%s-%d: Failed to run the plugin in %s: %s",
+ panel_module_get_name (external->module),
+ external->unique_id, program,
+ cmd_line != NULL ? error->message : "debugger not found");
+ g_error_free (error);
+
+ return;
+ }
+
+ g_free (program);
+ g_free (cmd_line);
}
/* spawn the proccess */
More information about the Xfce4-commits
mailing list