diff options
-rw-r--r-- | common/panel-debug.c | 54 | ||||
-rw-r--r-- | common/panel-debug.h | 9 | ||||
-rw-r--r-- | panel/panel-plugin-external.c | 67 | ||||
-rw-r--r-- | panel/panel-window.c | 2 |
4 files changed, 108 insertions, 24 deletions
diff --git a/common/panel-debug.c b/common/panel-debug.c index 31a62f29..b99e8cbf 100644 --- a/common/panel-debug.c +++ b/common/panel-debug.c @@ -28,16 +28,17 @@ #include <common/panel-debug.h> #include <common/panel-private.h> -enum -{ - DEBUG_LEVEL_UNKNOWN = 0, - DEBUG_LEVEL_NONE, - DEBUG_LEVEL_ENABLED -}; +PanelDebugFlag panel_debug_flags = 0; -gboolean panel_debug_enabled = FALSE; + + +/* additional debug levels */ +static const GDebugKey panel_debug_keys[] = +{ + { "gdb", PANEL_DEBUG_GDB } +}; @@ -46,10 +47,9 @@ panel_debug (const gchar *domain, const gchar *message, ...) { - static volatile gsize level__volatile = DEBUG_LEVEL_UNKNOWN; - gsize level; + static volatile gsize level__volatile = 0; const gchar *value; - gchar *string; + gchar *string, *path; va_list args; panel_return_if_fail (domain != NULL); @@ -60,15 +60,37 @@ panel_debug (const gchar *domain, { value = g_getenv ("PANEL_DEBUG"); if (G_UNLIKELY (value != NULL)) - level = DEBUG_LEVEL_ENABLED; - else - level = DEBUG_LEVEL_NONE; - - g_once_init_leave (&level__volatile, level); + { + panel_debug_flags = g_parse_debug_string (value, panel_debug_keys, + G_N_ELEMENTS (panel_debug_keys)); + + /* 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"); + if (G_LIKELY (path != NULL)) + { + g_printerr (PACKAGE_NAME "(debug): running plugins with %s; " + "log files stored in '%s'\n", path, g_get_tmp_dir ()); + g_free (path); + } + else + { + PANEL_UNSET_FLAG (panel_debug_flags, PANEL_DEBUG_GDB); + + g_printerr (PACKAGE_NAME "(debug): gdb not found in PATH; mode disabled\n"); + } + } + } + + g_once_init_leave (&level__volatile, 1); } /* leave when debug is disabled */ - if (level__volatile == DEBUG_LEVEL_NONE) + if (panel_debug_flags == 0) return; va_start (args, message); diff --git a/common/panel-debug.h b/common/panel-debug.h index 74990c5b..200758f3 100644 --- a/common/panel-debug.h +++ b/common/panel-debug.h @@ -30,7 +30,14 @@ #define PANEL_DEBUG_BOOL(bool) ((bool) ? "true" : "false") -extern gboolean panel_debug_enabled; +typedef enum +{ + PANEL_DEBUG_YES = 1 << 0, /* always enabled if PANEL_DEBUG is not %NULL */ + PANEL_DEBUG_GDB = 1 << 1 /* run plugin through gdb */ +} +PanelDebugFlag; + +extern PanelDebugFlag panel_debug_flags; void panel_debug (const gchar *domain, const gchar *message, diff --git a/panel/panel-plugin-external.c b/panel/panel-plugin-external.c index 8fb69604..0bdfff2e 100644 --- a/panel/panel-plugin-external.c +++ b/panel/panel-plugin-external.c @@ -487,16 +487,71 @@ panel_plugin_external_child_ask_restart (PanelPluginExternal *external) static void panel_plugin_external_child_spawn (PanelPluginExternal *external) { - gchar **argv; - GError *error = NULL; - gboolean succeed; - GPid pid; + gchar **argv, **dbg_argv, **tmp_argv; + GError *error = NULL; + gboolean succeed; + GPid pid; + gchar *gdb, *cmd_line; + guint i; + gint tmp_argc; + GTimeVal timestamp; panel_return_if_fail (PANEL_IS_PLUGIN_EXTERNAL (external)); panel_return_if_fail (GTK_WIDGET_REALIZED (external)); /* set plugin specific arguments */ argv = (*PANEL_PLUGIN_EXTERNAL_GET_CLASS (external)->get_argv) (external, external->priv->arguments); + panel_return_if_fail (argv != NULL); + + /* check debugging state */ + if (G_UNLIKELY (PANEL_HAS_FLAG (panel_debug_flags, PANEL_DEBUG_GDB))) + { + gdb = g_find_program_in_path ("gdb"); + if (G_LIKELY (gdb != NULL)) + { + 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)) + { + 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 parse the gdb command line: %s", + panel_module_get_name (external->module), + external->unique_id, error->message); + g_error_free (error); + + return; + } + + g_free (gdb); + g_free (cmd_line); + } + } /* spawn the proccess */ succeed = gdk_spawn_on_screen (gtk_widget_get_screen (GTK_WIDGET (external)), @@ -505,9 +560,9 @@ panel_plugin_external_child_spawn (PanelPluginExternal *external) NULL, &pid, &error); panel_debug (PANEL_DEBUG_DOMAIN_EXTERNAL, - "%s-%s: child spawned; pid=%d, socket-id=%s", + "%s-%d: child spawned; pid=%d, argc=%d", panel_module_get_name (external->module), - argv[PLUGIN_ARGV_UNIQUE_ID], pid, argv[PLUGIN_ARGV_SOCKET_ID]); + external->unique_id, pid, g_strv_length (argv)); if (G_LIKELY (succeed)) { diff --git a/panel/panel-window.c b/panel/panel-window.c index 35c53bce..fda3a23b 100644 --- a/panel/panel-window.c +++ b/panel/panel-window.c @@ -1461,7 +1461,7 @@ panel_window_screen_struts_set (PanelWindow *window) if (gdk_error_trap_pop () != 0) g_critical ("Failed to set the struts"); - if (panel_debug_enabled) + if (G_UNLIKELY (panel_debug_flags != 0)) { if (struts[STRUT_LEFT] != 0) n = STRUT_LEFT; |