[gimp/wip/bug792787-debug-stacktrace-GUI: 5/6] app: add a "generate-backtrace" preference in GimpCoreConfig.



commit b291042199621dde9435b4a8939e11e9f11c9c7b
Author: Jehan <jehan girinstud io>
Date:   Fri Jan 26 01:55:54 2018 +0100

    app: add a "generate-backtrace" preference in GimpCoreConfig.
    
    This will determine whether to output backtrace in a GUI and is disabled
    by default on stable, and activated in dev builds. It is a bit redundant
    with --stack-trace-mode option CLI and will take priority when enabled
    since most people would run GIMP with a graphical interface anyway.

 app/config/gimpcoreconfig.c      |   18 ++++++
 app/config/gimpcoreconfig.h      |    1 +
 app/config/gimprc-blurbs.h       |    3 +
 app/dialogs/preferences-dialog.c |   10 ++++
 app/errors.c                     |  110 +++++++++++++++++++++++++++-----------
 app/main.c                       |    2 +-
 app/signals.c                    |   15 +++---
 app/signals.h                    |    2 +-
 8 files changed, 119 insertions(+), 42 deletions(-)
---
diff --git a/app/config/gimpcoreconfig.c b/app/config/gimpcoreconfig.c
index 038fb51..87d31cc 100644
--- a/app/config/gimpcoreconfig.c
+++ b/app/config/gimpcoreconfig.c
@@ -113,6 +113,7 @@ enum
   PROP_EXPORT_METADATA_EXIF,
   PROP_EXPORT_METADATA_XMP,
   PROP_EXPORT_METADATA_IPTC,
+  PROP_GENERATE_BACKTRACE,
 
   /* ignored, only for backward compatibility: */
   PROP_INSTALL_COLORMAP,
@@ -654,6 +655,17 @@ gimp_core_config_class_init (GimpCoreConfigClass *klass)
                             FALSE,
                             GIMP_PARAM_STATIC_STRINGS);
 
+  GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_GENERATE_BACKTRACE,
+                            "generate-backtrace",
+                            "Try generating backtrace upon errors",
+                            GENERATE_BACKTRACE_BLURB,
+#ifdef GIMP_UNSTABLE
+                            TRUE,
+#else
+                            FALSE,
+#endif
+                            GIMP_PARAM_STATIC_STRINGS);
+
   /*  only for backward compatibility:  */
   GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_INSTALL_COLORMAP,
                             "install-colormap",
@@ -956,6 +968,9 @@ gimp_core_config_set_property (GObject      *object,
     case PROP_EXPORT_METADATA_IPTC:
       core_config->export_metadata_iptc = g_value_get_boolean (value);
       break;
+    case PROP_GENERATE_BACKTRACE:
+      core_config->generate_backtrace = g_value_get_boolean (value);
+      break;
 
     case PROP_INSTALL_COLORMAP:
     case PROP_MIN_COLORS:
@@ -1152,6 +1167,9 @@ gimp_core_config_get_property (GObject    *object,
     case PROP_EXPORT_METADATA_IPTC:
       g_value_set_boolean (value, core_config->export_metadata_iptc);
       break;
+    case PROP_GENERATE_BACKTRACE:
+      g_value_set_boolean (value, core_config->generate_backtrace);
+      break;
 
     case PROP_INSTALL_COLORMAP:
     case PROP_MIN_COLORS:
diff --git a/app/config/gimpcoreconfig.h b/app/config/gimpcoreconfig.h
index 517da39..57ed447 100644
--- a/app/config/gimpcoreconfig.h
+++ b/app/config/gimpcoreconfig.h
@@ -98,6 +98,7 @@ struct _GimpCoreConfig
   gboolean                export_metadata_exif;
   gboolean                export_metadata_xmp;
   gboolean                export_metadata_iptc;
+  gboolean                generate_backtrace;
 };
 
 struct _GimpCoreConfigClass
diff --git a/app/config/gimprc-blurbs.h b/app/config/gimprc-blurbs.h
index cb5e09c..384b528 100644
--- a/app/config/gimprc-blurbs.h
+++ b/app/config/gimprc-blurbs.h
@@ -210,6 +210,9 @@ _("Export XMP metadata by default.")
 #define EXPORT_METADATA_IPTC_BLURB \
 _("Export IPTC metadata by default.")
 
+#define GENERATE_BACKTRACE_BLURB \
+_("Try generating debug data for bug reporting when appropriate.")
+
 #define INITIAL_ZOOM_TO_FIT_BLURB \
 _("When enabled, this will ensure that the full image is visible after a " \
   "file is opened, otherwise it will be displayed with a scale of 1:1.")
diff --git a/app/dialogs/preferences-dialog.c b/app/dialogs/preferences-dialog.c
index e96074b..6fb75a6 100644
--- a/app/dialogs/preferences-dialog.c
+++ b/app/dialogs/preferences-dialog.c
@@ -1176,6 +1176,16 @@ prefs_dialog_new (Gimp       *gimp,
                           _("Use OpenCL"),
                           GTK_BOX (vbox2));
 
+#ifdef G_OS_UNIX
+  vbox2 = prefs_frame_new (_("Debugging"), GTK_CONTAINER (vbox),
+                           FALSE);
+
+  prefs_check_button_add (object, "generate-backtrace",
+                          _("Try generating debug data for bug reporting when appropriate.\n"
+                            "This will require \"gdb\" installed on your computer."),
+                          GTK_BOX (vbox2));
+#endif
+
   /*  Image Thumbnails  */
   vbox2 = prefs_frame_new (_("Image Thumbnails"), GTK_CONTAINER (vbox), FALSE);
 
diff --git a/app/errors.c b/app/errors.c
index 90c998a..64e7b30 100644
--- a/app/errors.c
+++ b/app/errors.c
@@ -199,8 +199,14 @@ gimp_message_log_func (const gchar    *log_domain,
   GimpMessageSeverity  severity = GIMP_MESSAGE_WARNING;
   Gimp                *gimp = data;
   gchar               *trace = NULL;
+  GimpCoreConfig      *config = gimp->config;
+  gboolean             generate_backtrace = FALSE;
 
-  if (flags & G_LOG_LEVEL_CRITICAL)
+  g_object_get (G_OBJECT (config),
+                "generate-backtrace", &generate_backtrace,
+                NULL);
+
+  if (generate_backtrace && (flags & G_LOG_LEVEL_CRITICAL))
     {
       severity = GIMP_MESSAGE_ERROR;
 
@@ -250,47 +256,87 @@ gimp_eek (const gchar *reason,
           const gchar *message,
           gboolean     use_handler)
 {
+  GimpCoreConfig *config = the_errors_gimp->config;
+  gboolean        generate_backtrace = FALSE;
+
+  /* GIMP has 2 ways to handle termination signals and fatal errors: one
+   * is the stack trace mode which is set at start as command line
+   * option --stack-trace-mode, this won't change for the length of the
+   * session and outputs a trace in terminal; the other is set in
+   * preferences, outputs a trace in a GUI and can change anytime during
+   * the session.
+   * The GUI backtrace has priority if it is set.
+   */
+  g_object_get (G_OBJECT (config),
+                "generate-backtrace", &generate_backtrace,
+                NULL);
+
 #ifndef G_OS_WIN32
   g_printerr ("%s: %s: %s\n", gimp_filename_to_utf8 (full_prog_name),
               reason, message);
 
   if (use_handler)
     {
-      switch (stack_trace_mode)
+#ifdef G_OS_UNIX
+      if (generate_backtrace)
         {
-        case GIMP_STACK_TRACE_NEVER:
-          break;
-
-        case GIMP_STACK_TRACE_QUERY:
-          /* Basically we don't have the "QUERY" case anymore, at least
-           * for now until I figure out something.
+          /* If enabled (it is disabled by default), the GUI preference
+           * takes precedence over the command line argument.
            */
-        case GIMP_STACK_TRACE_ALWAYS:
-          {
-#if defined(G_OS_UNIX)
-            gchar   *args[6] = { "gimpdebug-2.0", full_prog_name, NULL,
-                                 (gchar *) reason, (gchar *) message, NULL };
-            gchar    pid[16];
-            gint     exit_status;
-
-            g_snprintf (pid, 16, "%u", (guint) getpid ());
-            args[2] = pid;
-
-            /* We don't care about any return value. If it fails, too
-             * bad, we just won't have any stack trace.
-             * We still need to use the sync() variant because we have
-             * to keep GIMP up long enough for the debugger to get its
-             * trace.
-             */
-            g_spawn_sync (NULL, args, NULL,
-                          G_SPAWN_SEARCH_PATH | G_SPAWN_STDERR_TO_DEV_NULL | G_SPAWN_STDOUT_TO_DEV_NULL,
-                          NULL, NULL, NULL, NULL, &exit_status, NULL);
+          gchar *args[6] = { "gimpdebug-2.0", full_prog_name, NULL,
+                             (gchar *) reason, (gchar *) message, NULL };
+          gchar  pid[16];
+          gint   exit_status;
+
+          g_snprintf (pid, 16, "%u", (guint) getpid ());
+          args[2] = pid;
+
+          /* We don't care about any return value. If it fails, too
+           * bad, we just won't have any stack trace.
+           * We still need to use the sync() variant because we have
+           * to keep GIMP up long enough for the debugger to get its
+           * trace.
+           */
+          g_spawn_sync (NULL, args, NULL,
+                        G_SPAWN_SEARCH_PATH | G_SPAWN_STDERR_TO_DEV_NULL | G_SPAWN_STDOUT_TO_DEV_NULL,
+                        NULL, NULL, NULL, NULL, &exit_status, NULL);
+        }
+      else
 #endif
-          }
-          break;
+        {
+          switch (stack_trace_mode)
+            {
+            case GIMP_STACK_TRACE_NEVER:
+              break;
+
+            case GIMP_STACK_TRACE_QUERY:
+                {
+                  sigset_t sigset;
+
+                  sigemptyset (&sigset);
+                  sigprocmask (SIG_SETMASK, &sigset, NULL);
+
+                  if (the_errors_gimp)
+                    gimp_gui_ungrab (the_errors_gimp);
+
+                  g_on_error_query (full_prog_name);
+                }
+              break;
+
+            case GIMP_STACK_TRACE_ALWAYS:
+                {
+                  sigset_t sigset;
+
+                  sigemptyset (&sigset);
+                  sigprocmask (SIG_SETMASK, &sigset, NULL);
+
+                  g_on_error_stack_trace (full_prog_name);
+                }
+              break;
 
-        default:
-          break;
+            default:
+              break;
+            }
         }
     }
 #else
diff --git a/app/main.c b/app/main.c
index 339439d..603ff60 100644
--- a/app/main.c
+++ b/app/main.c
@@ -540,7 +540,7 @@ main (int    argc,
   if (abort_message)
     app_abort (no_interface, abort_message);
 
-  gimp_init_signal_handlers (stack_trace_mode);
+  gimp_init_signal_handlers ();
 
   if (system_gimprc)
     system_gimprc_file = g_file_new_for_commandline_arg (system_gimprc);
diff --git a/app/signals.c b/app/signals.c
index 11fad52..76d5d4a 100644
--- a/app/signals.c
+++ b/app/signals.c
@@ -25,6 +25,8 @@
 
 #include "core/core-types.h"
 
+#include "core/gimp.h"
+
 #include "errors.h"
 #include "signals.h"
 
@@ -35,7 +37,7 @@ static void  gimp_sigfatal_handler (gint sig_num) G_GNUC_NORETURN;
 
 
 void
-gimp_init_signal_handlers (GimpStackTraceMode stack_trace_mode)
+gimp_init_signal_handlers (void)
 {
 #ifndef G_OS_WIN32
   /* No use catching these on Win32, the user won't get any stack
@@ -54,13 +56,10 @@ gimp_init_signal_handlers (GimpStackTraceMode stack_trace_mode)
   gimp_signal_private (SIGABRT, gimp_sigfatal_handler, 0);
   gimp_signal_private (SIGTERM, gimp_sigfatal_handler, 0);
 
-  if (stack_trace_mode != GIMP_STACK_TRACE_NEVER)
-    {
-      /* these are handled by gimp_fatal_error() */
-      gimp_signal_private (SIGBUS,  gimp_sigfatal_handler, 0);
-      gimp_signal_private (SIGSEGV, gimp_sigfatal_handler, 0);
-      gimp_signal_private (SIGFPE,  gimp_sigfatal_handler, 0);
-    }
+  /* these are handled by gimp_fatal_error() */
+  gimp_signal_private (SIGBUS,  gimp_sigfatal_handler, 0);
+  gimp_signal_private (SIGSEGV, gimp_sigfatal_handler, 0);
+  gimp_signal_private (SIGFPE,  gimp_sigfatal_handler, 0);
 
   /* Ignore SIGPIPE because plug_in.c handles broken pipes */
   gimp_signal_private (SIGPIPE, SIG_IGN, 0);
diff --git a/app/signals.h b/app/signals.h
index f04e82f..c846f96 100644
--- a/app/signals.h
+++ b/app/signals.h
@@ -23,7 +23,7 @@
 #endif
 
 
-void   gimp_init_signal_handlers (GimpStackTraceMode stack_trace_mode);
+void   gimp_init_signal_handlers (void);
 
 
 #endif /* __SIGNALS_H__ */


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