[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 (&timestamp);
+      cmd_line = NULL;
+      program = NULL;
+
+      if (PANEL_HAS_FLAG (panel_debug_flags, PANEL_DEBUG_GDB))
         {
-          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))
+          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