From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= Date: Tue, 24 Oct 2017 03:20:34 +0200 Subject: 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 Bug-GNOME: https://bugzilla.gnome.org/show_bug.cgi?id=789377 Forwarded: https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/6 --- src/main.c | 76 +++++++++++++++++++++++++++++++++++++++++------------- src/shell-global.c | 10 ++++--- 2 files changed, 65 insertions(+), 21 deletions(-) diff --git a/src/main.c b/src/main.c index 726afe9..047ea87 100644 --- a/src/main.c +++ b/src/main.c @@ -34,16 +34,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, @@ -278,13 +288,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 }; + + 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; + } - _shell_debug = g_parse_debug_string (debug_string, keys, - G_N_ELEMENTS (keys)); + return g_strjoinv (":", (char**) enabled_flags); } static GLogWriterOutput @@ -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)) { @@ -541,8 +574,9 @@ int main (int argc, char **argv) { g_autoptr (MetaContext) context = NULL; + g_autofree char *debug_flags_string = NULL; GError *error = NULL; - const char *debug_flags; + const char *shell_debug; int ecode = EXIT_SUCCESS; bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); @@ -580,8 +614,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_context_is_replacing (context)); shell_a11y_init (); @@ -596,7 +636,7 @@ 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_signal_connect (shell_global_get (), "notify::debug-flags", diff --git a/src/shell-global.c b/src/shell-global.c index 1676208..60b84e6 100644 --- a/src/shell-global.c +++ b/src/shell-global.c @@ -1890,11 +1890,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,