[retro-gtk] runner-process: Print the backtrace without running in gdb



commit 42897842b150cf7c60d870e282e4b703ba3c92f4
Author: Adrien Plazas <kekun plazas laposte net>
Date:   Mon Dec 14 19:52:34 2020 +0100

    runner-process: Print the backtrace without running in gdb
    
    This catches SIGSEGV to print the backtrace via g_on_error_stack_trace()
    when RETRO_DEBUG is set to 1 instead of running in gdb, speeding up the
    runner process with debug log enabled.

 retro-gtk/retro-runner-process.c | 41 ++++++----------------------------------
 retro-runner/retro-runner.c      | 26 ++++++++++++++++++++++++-
 2 files changed, 31 insertions(+), 36 deletions(-)
---
diff --git a/retro-gtk/retro-runner-process.c b/retro-gtk/retro-runner-process.c
index 8551c33..953ad69 100644
--- a/retro-gtk/retro-runner-process.c
+++ b/retro-gtk/retro-runner-process.c
@@ -218,23 +218,6 @@ create_connection (GSubprocessLauncher  *launcher,
   return connection;
 }
 
-static gboolean
-is_debug (void)
-{
-  gchar **envp;
-  const gchar *env_value;
-  gboolean result = FALSE;
-
-  envp = g_get_environ ();
-  env_value = g_environ_getenv (envp, "RETRO_DEBUG");
-
-  result = (g_strcmp0 ("1", env_value) == 0);
-
-  g_strfreev (envp);
-
-  return result;
-}
-
 /**
  * retro_runner_process_start:
  * @self: a #RetroRunnerProcess
@@ -260,24 +243,12 @@ retro_runner_process_start (RetroRunnerProcess  *self,
   if (!(connection = create_connection (launcher, 3, error)))
     return;
 
-  if (is_debug ()) {
-    if (!(process = g_subprocess_launcher_spawn (launcher, &tmp_error,
-                                                 "gdb", "-batch", "-ex", "run",
-                                                 "-ex", "bt", "--args",
-                                                 RETRO_RUNNER_PATH,
-                                                 g_get_application_name (),
-                                                 self->filename, NULL))) {
-      g_propagate_error (error, tmp_error);
-      return;
-    }
-  } else {
-    if (!(process = g_subprocess_launcher_spawn (launcher, &tmp_error,
-                                                 RETRO_RUNNER_PATH,
-                                                 g_get_application_name (),
-                                                 self->filename, NULL))) {
-      g_propagate_error (error, tmp_error);
-      return;
-    }
+  if (!(process = g_subprocess_launcher_spawn (launcher, &tmp_error,
+                                               RETRO_RUNNER_PATH,
+                                               g_get_application_name (),
+                                               self->filename, NULL))) {
+    g_propagate_error (error, tmp_error);
+    return;
   }
 
   if (!(self->connection = g_dbus_connection_new_sync (G_IO_STREAM (connection),
diff --git a/retro-runner/retro-runner.c b/retro-runner/retro-runner.c
index 8fe3a09..e7057d0 100644
--- a/retro-runner/retro-runner.c
+++ b/retro-runner/retro-runner.c
@@ -13,8 +13,11 @@
 #endif
 
 #include "ipc-runner-impl-private.h"
+#include "retro-debug-private.h"
 #include "retro-pa-player-private.h"
 
+#define RETRO_RUNNER_PRGNAME "retro-runner"
+
 static gboolean
 run_main_loop (GMainLoop        *loop,
                GDBusConnection  *connection,
@@ -43,6 +46,16 @@ run_main_loop (GMainLoop        *loop,
   return TRUE;
 }
 
+static void
+print_backtrace_on_sigsegv_cb (int        sig,
+                               siginfo_t *si,
+                               void      *unused)
+{
+  g_on_error_stack_trace (RETRO_RUNNER_PRGNAME);
+
+  exit (EXIT_FAILURE);
+}
+
 /* Adapted from GNOME Builder's gnome-builder-git.c */
 gint
 main (gint    argc,
@@ -58,7 +71,7 @@ main (gint    argc,
   /* Arguments: application name, core filename */
   g_assert (argc >= 3);
 
-  g_set_prgname ("retro-runner");
+  g_set_prgname (RETRO_RUNNER_PRGNAME);
   g_set_application_name (argv[1]);
 
 #ifdef __linux__
@@ -69,6 +82,17 @@ main (gint    argc,
 #error "Please submit a patch to support parent-death signal on your OS"
 #endif
 
+  if (G_UNLIKELY (retro_is_debug ())) {
+    struct sigaction sa;
+
+    sa.sa_flags = SA_SIGINFO;
+    sigemptyset (&sa.sa_mask);
+    sa.sa_sigaction = print_backtrace_on_sigsegv_cb;
+
+    if (G_UNLIKELY (sigaction (SIGSEGV, &sa, NULL) == -1))
+      g_critical ("Couldn't set a SIGSEGV handler.");
+  }
+
   loop = g_main_loop_new (NULL, FALSE);
 
   g_debug ("Starting runner process");


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