[gnome-shell/dynamic-debug-flags: 2/2] main: increase the granularity of backtraces in SHELL_DEBUG



commit f55af07ad58fc55d7bcc86ac5a8642aa4858895e
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date:   Mon Oct 23 20:20:34 2017 -0500

    main: increase the granularity of backtraces in SHELL_DEBUG
    
    Add support for multiple debug-keys for getting the backtraces,
    allowing more control using both SHELL_DEBUG and/or set_debug_flags
    
    https://bugzilla.gnome.org/show_bug.cgi?id=789377

 src/main.c         | 77 +++++++++++++++++++++++++++++++++++++++++-------------
 src/shell-global.c | 10 ++++---
 2 files changed, 66 insertions(+), 21 deletions(-)
---
diff --git a/src/main.c b/src/main.c
index 3b6d7323c..7ea7c6e22 100644
--- a/src/main.c
+++ b/src/main.c
@@ -39,16 +39,26 @@ extern GType gnome_shell_plugin_get_type (void);
 static gboolean is_gdm_mode = FALSE;
 static char *session_mode = NULL;
 static int caught_signal = 0;
+static gboolean _tracked_signals[NSIG] = { 0 };
 
 #define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1
 #define DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER 4
 
 enum {
-  SHELL_DEBUG_BACKTRACE_WARNINGS = 1,
-  SHELL_DEBUG_BACKTRACE_SEGFAULTS = 2,
+  SHELL_DEBUG_BACKTRACE_WARNINGS  = (1 << 0),
+  SHELL_DEBUG_BACKTRACE_SEGFAULTS = (1 << 1),
+  SHELL_DEBUG_BACKTRACE_ABORTS    = (1 << 2),
+  SHELL_DEBUG_BACKTRACE_FPE       = (1 << 3),
 };
-static int _shell_debug;
-static gboolean _tracked_signals[NSIG] = { 0 };
+static const GDebugKey SHELL_DEBUG_KEYS[] = {
+  { "backtrace-warnings",    SHELL_DEBUG_BACKTRACE_WARNINGS },
+  { "backtrace-segfaults",   SHELL_DEBUG_BACKTRACE_SEGFAULTS },
+  { "backtrace-aborts",      SHELL_DEBUG_BACKTRACE_ABORTS },
+  { "backtrace-math-errors", SHELL_DEBUG_BACKTRACE_FPE },
+};
+static int _default_debug_flags = SHELL_DEBUG_BACKTRACE_ABORTS |
+                                  SHELL_DEBUG_BACKTRACE_FPE;
+static int _shell_debug = 0;
 
 static void
 shell_dbus_acquire_name (GDBusProxy  *bus,
@@ -292,13 +302,23 @@ shell_a11y_init (void)
 static void
 shell_update_debug (const char *debug_string)
 {
-  static const GDebugKey keys[] = {
-    { "backtrace-warnings", SHELL_DEBUG_BACKTRACE_WARNINGS },
-    { "backtrace-segfaults", SHELL_DEBUG_BACKTRACE_SEGFAULTS },
-  };
+  _shell_debug = g_parse_debug_string (debug_string, SHELL_DEBUG_KEYS,
+                                       G_N_ELEMENTS (SHELL_DEBUG_KEYS));
+}
+
+static char *
+debug_flags_to_string (void)
+{
+  gsize i, j;
+  const char *enabled_flags[G_N_ELEMENTS (SHELL_DEBUG_KEYS) + 1] = { 0 };
 
-  _shell_debug = g_parse_debug_string (debug_string, keys,
-                                       G_N_ELEMENTS (keys));
+  for (i = 0, j = 0; i < G_N_ELEMENTS (SHELL_DEBUG_KEYS); ++i)
+    {
+      if ((_shell_debug & SHELL_DEBUG_KEYS[i].value))
+        enabled_flags[j++] = SHELL_DEBUG_KEYS[i].key;
+    }
+
+  return g_strjoinv (":", (char**) enabled_flags);
 }
 
 static void
@@ -395,10 +415,23 @@ reset_signal_handler_to_default (int signo)
 static void
 setup_debug_signal_listners (void)
 {
-  dump_gjs_stack_on_signal (SIGABRT);
-  dump_gjs_stack_on_signal (SIGFPE);
-  dump_gjs_stack_on_signal (SIGIOT);
-  dump_gjs_stack_on_signal (SIGTRAP);
+  if ((_shell_debug & SHELL_DEBUG_BACKTRACE_ABORTS))
+    {
+      dump_gjs_stack_on_signal (SIGABRT);
+      dump_gjs_stack_on_signal (SIGIOT);
+      dump_gjs_stack_on_signal (SIGTRAP);
+    }
+  else
+    {
+      reset_signal_handler_to_default (SIGABRT);
+      reset_signal_handler_to_default (SIGIOT);
+      reset_signal_handler_to_default (SIGTRAP);
+    }
+
+  if ((_shell_debug & SHELL_DEBUG_BACKTRACE_FPE))
+    dump_gjs_stack_on_signal (SIGFPE);
+  else
+    reset_signal_handler_to_default (SIGFPE);
 
   if ((_shell_debug & SHELL_DEBUG_BACKTRACE_SEGFAULTS))
     {
@@ -499,7 +532,8 @@ main (int argc, char **argv)
 {
   GOptionContext *ctx;
   GError *error = NULL;
-  const char *debug_flags;
+  const char *shell_debug;
+  char *debug_flags_string;
   int ecode;
 
   bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
@@ -535,8 +569,14 @@ main (int argc, char **argv)
   g_setenv ("GJS_DEBUG_OUTPUT", "stderr", TRUE);
   g_setenv ("GJS_DEBUG_TOPICS", "JS ERROR;JS LOG", TRUE);
 
-  debug_flags = g_getenv ("SHELL_DEBUG");
-  shell_update_debug (debug_flags);
+  shell_debug = g_getenv ("SHELL_DEBUG");
+
+  if (shell_debug)
+    shell_update_debug (shell_debug);
+  else
+    _shell_debug = _default_debug_flags;
+
+  debug_flags_string = debug_flags_to_string ();
 
   shell_dbus_init (meta_get_replace_current_wm ());
   shell_a11y_init ();
@@ -551,8 +591,9 @@ main (int argc, char **argv)
     session_mode = is_gdm_mode ? (char *)"gdm" : (char *)"user";
 
   _shell_global_init ("session-mode", session_mode,
-                      "debug-flags", debug_flags,
+                      "debug-flags", debug_flags_string,
                       NULL);
+  g_free (debug_flags_string);
 
   g_signal_connect (shell_global_get (), "notify::debug-flags",
                     G_CALLBACK (global_notify_debug_flags), NULL);
diff --git a/src/shell-global.c b/src/shell-global.c
index 5ef8dec8e..17a748791 100644
--- a/src/shell-global.c
+++ b/src/shell-global.c
@@ -2048,11 +2048,15 @@ shell_global_get_debug_flags (ShellGlobal *global)
 /**
  * shell_global_set_debug_flags:
  * @global: a #ShellGlobal
- * @debug_flags: (nullable): A string for debugging flags
+ * @debug_flags: (nullable): A comma-separated string of debugging flags
  *
  * Updates the debugging flags at runtime as the one set using the SHELL_DEBUG
- * environment variables. Currently we support 'backtrace-warnings' and
- * 'backtrace-segfaults' keys.
+ * environment variables. Currently we support these keys:
+ *  - 'backtrace-warnings'
+ *  - 'backtrace-segfaults'
+ *  - 'backtrace-aborts'
+ *  - 'backtrace-math-errors'
+ *  - 'all'
  */
 void
 shell_global_set_debug_flags (ShellGlobal  *global,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]