[gimp/wip/bug792787-debug-stacktrace-GUI: 2/3] app: reimplement gimp_get_stack_trace().
- From: Jehan Pagès <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/wip/bug792787-debug-stacktrace-GUI: 2/3] app: reimplement gimp_get_stack_trace().
- Date: Thu, 25 Jan 2018 18:22:30 +0000 (UTC)
commit d31295d46c198041e0572a6659ed44a2c2543503
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]