[Xfce4-commits] <xfce4-panel:master> Add debug mode to run plugins in gdb.

Nick Schermer noreply at xfce.org
Wed Jul 14 22:48:02 CEST 2010


Updating branch refs/heads/master
         to dc8625abcd28f218694b736e7c560652bbab5117 (commit)
       from b09727368607c0e943ff24f977eff67bd842f9a5 (commit)

commit dc8625abcd28f218694b736e7c560652bbab5117
Author: Nick Schermer <nick at xfce.org>
Date:   Wed Jul 14 22:40:48 2010 +0200

    Add debug mode to run plugins in gdb.
    
    With PANEL_DEBUG=gdb plugin will be started in gdb
    and log files (with backtrace and register dump) are
    automatically stored in /tmp.
    Some functionality will not be available, like
    automatically restart the plugins.
    
    Also cleanup the debug level handling a bit, so it is
    easier to extend and make struts debugging work again.

 common/panel-debug.c          |   54 +++++++++++++++++++++++----------
 common/panel-debug.h          |    9 +++++-
 panel/panel-plugin-external.c |   67 +++++++++++++++++++++++++++++++++++++----
 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 31a62f2..b99e8cb 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 74990c5..200758f 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 8fb6960..0bdfff2 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 (&timestamp);
+          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 35c53bc..fda3a23 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;



More information about the Xfce4-commits mailing list