Commit bb88a2d5 authored by Jehan's avatar Jehan

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.
parent 9fdf3555
......@@ -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];
/* 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,
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;
return trace;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment