[gimp] app: cleanly remove log handlers on exit



commit 2e643e62706fd235a4beb0a4cbe1404fdc317667
Author: Ell <ell_se yahoo com>
Date:   Thu May 3 15:43:19 2018 -0400

    app: cleanly remove log handlers on exit
    
    Remove the log handlers registered in errors_init(), in
    errors_exit(), and call errors_exit() before destroying the Gimp
    instance, since the log handlers depend on it.  This avoids
    segfaulting if a message is logged after destroying the Gimp
    instance.

 app/app.c    |    3 +-
 app/errors.c |  104 ++++++++++++++++++++++++++++++++-------------------------
 2 files changed, 60 insertions(+), 47 deletions(-)
---
diff --git a/app/app.c b/app/app.c
index 9fe49f4..4bfdc69 100644
--- a/app/app.c
+++ b/app/app.c
@@ -441,11 +441,12 @@ app_run (const gchar         *full_prog_name,
 
   gimp_gegl_exit (gimp);
 
+  errors_exit ();
+
   g_object_unref (gimp);
 
   gimp_debug_instances ();
 
-  errors_exit ();
   gegl_exit ();
 }
 
diff --git a/app/errors.c b/app/errors.c
index ff0b8e0..d88590a 100644
--- a/app/errors.c
+++ b/app/errors.c
@@ -51,12 +51,48 @@
 
 /*  private variables  */
 
+static const gchar * const log_domains[] =
+{
+  "Gimp",
+  "Gimp-Actions",
+  "Gimp-Base",
+  "Gimp-Composite",
+  "Gimp-Config",
+  "Gimp-Core",
+  "Gimp-Dialogs",
+  "Gimp-Display",
+  "Gimp-File",
+  "Gimp-GEGL",
+  "Gimp-GUI",
+  "Gimp-Menus",
+  "Gimp-Operations",
+  "Gimp-PDB",
+  "Gimp-Paint",
+  "Gimp-Paint-Funcs",
+  "Gimp-Plug-In",
+  "Gimp-Text",
+  "Gimp-Tools",
+  "Gimp-Vectors",
+  "Gimp-Widgets",
+  "Gimp-XCF",
+  "LibGimpBase",
+  "LibGimpColor",
+  "LibGimpConfig",
+  "LibGimpMath",
+  "LibGimpModule",
+  "LibGimpThumb",
+  "LibGimpWidgets"
+};
+
 static Gimp                *the_errors_gimp   = NULL;
 static gboolean             use_debug_handler = FALSE;
 static GimpStackTraceMode   stack_trace_mode  = GIMP_STACK_TRACE_QUERY;
 static gchar               *full_prog_name    = NULL;
 static gchar               *backtrace_file    = NULL;
 static gchar               *backup_path       = NULL;
+static guint                log_domain_handler_ids[G_N_ELEMENTS (log_domains)];
+static guint                gegl_handler_id   = 0;
+static guint                global_handler_id = 0;
 
 
 /*  local function prototypes  */
@@ -84,38 +120,6 @@ errors_init (Gimp               *gimp,
              GimpStackTraceMode  _stack_trace_mode,
              const gchar        *_backtrace_file)
 {
-  const gchar * const log_domains[] =
-  {
-    "Gimp",
-    "Gimp-Actions",
-    "Gimp-Base",
-    "Gimp-Composite",
-    "Gimp-Config",
-    "Gimp-Core",
-    "Gimp-Dialogs",
-    "Gimp-Display",
-    "Gimp-File",
-    "Gimp-GEGL",
-    "Gimp-GUI",
-    "Gimp-Menus",
-    "Gimp-Operations",
-    "Gimp-PDB",
-    "Gimp-Paint",
-    "Gimp-Paint-Funcs",
-    "Gimp-Plug-In",
-    "Gimp-Text",
-    "Gimp-Tools",
-    "Gimp-Vectors",
-    "Gimp-Widgets",
-    "Gimp-XCF",
-    "LibGimpBase",
-    "LibGimpColor",
-    "LibGimpConfig",
-    "LibGimpMath",
-    "LibGimpModule",
-    "LibGimpThumb",
-    "LibGimpWidgets"
-  };
   gint i;
 
   g_return_if_fail (GIMP_IS_GIMP (gimp));
@@ -146,25 +150,33 @@ errors_init (Gimp               *gimp,
                                   "backup-XXX.xcf", NULL);
 
   for (i = 0; i < G_N_ELEMENTS (log_domains); i++)
-    g_log_set_handler (log_domains[i],
-                       G_LOG_LEVEL_WARNING |
-                       G_LOG_LEVEL_MESSAGE |
-                       G_LOG_LEVEL_CRITICAL,
-                       gimp_message_log_func, gimp);
-
-  g_log_set_handler ("GEGL",
-                     G_LOG_LEVEL_WARNING |
-                     G_LOG_LEVEL_MESSAGE |
-                     G_LOG_LEVEL_CRITICAL,
-                     gimp_message_log_func, gimp);
-  g_log_set_handler (NULL,
-                     G_LOG_LEVEL_ERROR | G_LOG_FLAG_FATAL,
-                     gimp_error_log_func, gimp);
+    log_domain_handler_ids[i] = g_log_set_handler (log_domains[i],
+                                                   G_LOG_LEVEL_WARNING |
+                                                   G_LOG_LEVEL_MESSAGE |
+                                                   G_LOG_LEVEL_CRITICAL,
+                                                   gimp_message_log_func, gimp);
+
+  gegl_handler_id   = g_log_set_handler ("GEGL",
+                                         G_LOG_LEVEL_WARNING |
+                                         G_LOG_LEVEL_MESSAGE |
+                                         G_LOG_LEVEL_CRITICAL,
+                                         gimp_message_log_func, gimp);
+  global_handler_id = g_log_set_handler (NULL,
+                                         G_LOG_LEVEL_ERROR | G_LOG_FLAG_FATAL,
+                                         gimp_error_log_func, gimp);
 }
 
 void
 errors_exit (void)
 {
+  gint i;
+
+  for (i = 0; i < G_N_ELEMENTS (log_domains); i++)
+    g_log_remove_handler (log_domains[i], log_domain_handler_ids[i]);
+
+  g_log_remove_handler ("GEGL", gegl_handler_id);
+  g_log_remove_handler (NULL, global_handler_id);
+
   the_errors_gimp = NULL;
 
   if (backtrace_file)


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