[gimp/wip/bug792787-debug-stacktrace-GUI: 3/6] app: reimplement gimp_get_stack_trace().



commit cc7675e082dff4048345e50edf28966deddf75a0
Author: Jehan <jehan girinstud io>
Date:   Thu Jan 25 03:41:51 2018 +0100

    app: reimplement gimp_get_stack_trace().
    
    Don't use g_on_error_stack_trace() from glib anymore. It is
    over-complicated, using gdb in interactive mode and running command
    writing in the pipe input. Sometimes it even gets stuck and never
    return. This is useless since gdb even has a batch mode, to just run
    commands and exit directly. I just use this.

 app/errors.c |   72 +++++++++------------------------------------------------
 1 files changed, 12 insertions(+), 60 deletions(-)
---
diff --git a/app/errors.c b/app/errors.c
index e254792..48fa176 100644
--- a/app/errors.c
+++ b/app/errors.c
@@ -307,12 +307,10 @@ gimp_get_stack_trace (void)
 {
   gchar   *trace  = NULL;
 #if defined(G_OS_UNIX)
-  GString *gtrace = NULL;
-  gchar    buffer[256];
-  ssize_t  read_n;
-  pid_t    pid;
-  int      status;
-  int      out_fd[2];
+  gchar   *args[7] = { "gdb", "-batch", "-ex", "backtrace full",
+                       full_prog_name, NULL, NULL };
+  gchar   *gdb_stdout;
+  gchar    pid[16];
 #endif
 
   /* Though we should theoretically ask with GIMP_STACK_TRACE_QUERY, we
@@ -325,66 +323,20 @@ gimp_get_stack_trace (void)
    * another method, probably with DrMingW.
    */
 #if defined(G_OS_UNIX)
-  if (pipe (out_fd) == -1)
-    {
-      return NULL;
-    }
-
-  /* This is a trick to get the stack trace inside a string.
-   * GLib's g_on_error_stack_trace() unfortunately writes directly to
-   * the standard output, which is a very unfortunate implementation.
-   */
-  pid = fork ();
-  if (pid == 0)
-    {
-      /* Child process. */
+  g_snprintf (pid, 16, "%u", (guint) getpid ());
+  args[5] = pid;
 
-      /* XXX I just don't understand why, but somehow the parent process
-       * doesn't get the output if I don't print something first. I just
-       * leave this very dirty hack until I figure out what's going on.
-       */
-      printf(" ");
-
-      /* Redirect the debugger output. */
-      dup2 (out_fd[1], STDOUT_FILENO);
-      close (out_fd[0]);
-      close (out_fd[1]);
-      g_on_error_stack_trace (full_prog_name);
-      _exit (0);
-    }
-  else if (pid > 0)
+  if (g_spawn_sync (NULL, args, NULL,
+                    G_SPAWN_SEARCH_PATH | G_SPAWN_STDERR_TO_DEV_NULL,
+                    NULL, NULL, &gdb_stdout, NULL, NULL, NULL))
     {
-      /* Main process. */
-      waitpid (pid, &status, 0);
+      trace = g_strdup (gdb_stdout);
     }
-  else if (pid == (pid_t) -1)
+  else if (gdb_stdout)
     {
-      /* No trace can be done. */
-      return NULL;
+      g_free (gdb_stdout);
     }
 
-  gtrace = g_string_new ("");
-
-  /* It is important to close the writing side of the pipe, otherwise
-   * the read() will wait forever without getting the information that
-   * writing is finished.
-   */
-  close (out_fd[1]);
-
-  while ((read_n = read (out_fd[0], buffer, 256)) > 0)
-    {
-      g_string_append_len (gtrace, buffer, read_n);
-    }
-  close (out_fd[0]);
-
-  if (gtrace)
-    trace = g_string_free (gtrace, FALSE);
-  if (trace && strlen (g_strstrip (trace)) == 0)
-    {
-      /* Empty strings are the same as no strings. */
-      g_free (trace);
-      trace = NULL;
-    }
 #endif
 
   return trace;


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