Blame src/main.c

Packit d345d1
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
Packit d345d1
Packit d345d1
#include "config.h"
Packit d345d1
Packit d345d1
#ifdef HAVE_MALLINFO
Packit d345d1
#include <malloc.h>
Packit d345d1
#endif
Packit d345d1
#include <stdlib.h>
Packit d345d1
#include <string.h>
Packit d345d1
Packit d345d1
#include <cogl-pango/cogl-pango.h>
Packit d345d1
#include <clutter/clutter.h>
Packit d345d1
#include <clutter/x11/clutter-x11.h>
Packit d345d1
#include <gtk/gtk.h>
Packit d345d1
#include <glib/gi18n-lib.h>
Packit d345d1
#include <girepository.h>
Packit d345d1
#include <meta/main.h>
Packit d345d1
#include <meta/meta-plugin.h>
Packit d345d1
#include <meta/prefs.h>
Packit d345d1
#include <atk-bridge.h>
Packit d345d1
Packit d345d1
#include "shell-global.h"
Packit d345d1
#include "shell-global-private.h"
Packit d345d1
#include "shell-perf-log.h"
Packit d345d1
#include "st.h"
Packit d345d1
Packit d345d1
extern GType gnome_shell_plugin_get_type (void);
Packit d345d1
Packit d345d1
#define SHELL_DBUS_SERVICE "org.gnome.Shell"
Packit d345d1
#define MAGNIFIER_DBUS_SERVICE "org.gnome.Magnifier"
Packit d345d1
Packit d345d1
#define WM_NAME "GNOME Shell"
Packit d345d1
#define GNOME_WM_KEYBINDINGS "Mutter,GNOME Shell"
Packit d345d1
Packit d345d1
static gboolean is_gdm_mode = FALSE;
Packit d345d1
static char *session_mode = NULL;
Packit d345d1
static int caught_signal = 0;
Packit d345d1
Packit d345d1
#define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1
Packit d345d1
#define DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER 4
Packit d345d1
Packit d345d1
enum {
Packit d345d1
  SHELL_DEBUG_BACKTRACE_WARNINGS = 1,
Packit d345d1
  SHELL_DEBUG_BACKTRACE_SEGFAULTS = 2,
Packit d345d1
};
Packit d345d1
static int _shell_debug;
Packit d345d1
static gboolean _tracked_signals[NSIG] = { 0 };
Packit d345d1
Packit d345d1
static void
Packit d345d1
shell_dbus_acquire_name (GDBusProxy  *bus,
Packit d345d1
                         guint32      request_name_flags,
Packit d345d1
                         guint32     *request_name_result,
Packit d345d1
                         const gchar *name,
Packit d345d1
                         gboolean     fatal)
Packit d345d1
{
Packit d345d1
  GError *error = NULL;
Packit d345d1
  GVariant *request_name_variant;
Packit d345d1
Packit d345d1
  if (!(request_name_variant = g_dbus_proxy_call_sync (bus,
Packit d345d1
                                                       "RequestName",
Packit d345d1
                                                       g_variant_new ("(su)", name, request_name_flags),
Packit d345d1
                                                       0, /* call flags */
Packit d345d1
                                                       -1, /* timeout */
Packit d345d1
                                                       NULL, /* cancellable */
Packit d345d1
                                                       &error)))
Packit d345d1
    {
Packit d345d1
      g_printerr ("failed to acquire %s: %s\n", name, error->message);
Packit d345d1
      g_clear_error (&error);
Packit d345d1
      if (!fatal)
Packit d345d1
        return;
Packit d345d1
      exit (1);
Packit d345d1
    }
Packit d345d1
  g_variant_get (request_name_variant, "(u)", request_name_result);
Packit d345d1
  g_variant_unref (request_name_variant);
Packit d345d1
}
Packit d345d1
Packit d345d1
static void
Packit d345d1
shell_dbus_acquire_names (GDBusProxy  *bus,
Packit d345d1
                          guint32      request_name_flags,
Packit d345d1
                          const gchar *name,
Packit d345d1
                          gboolean     fatal, ...) G_GNUC_NULL_TERMINATED;
Packit d345d1
Packit d345d1
static void
Packit d345d1
shell_dbus_acquire_names (GDBusProxy  *bus,
Packit d345d1
                          guint32      request_name_flags,
Packit d345d1
                          const gchar *name,
Packit d345d1
                          gboolean     fatal, ...)
Packit d345d1
{
Packit d345d1
  va_list al;
Packit d345d1
  guint32 request_name_result;
Packit d345d1
  va_start (al, fatal);
Packit d345d1
  for (;;)
Packit d345d1
  {
Packit d345d1
    shell_dbus_acquire_name (bus,
Packit d345d1
                             request_name_flags,
Packit d345d1
                             &request_name_result,
Packit d345d1
                             name, fatal);
Packit d345d1
    name = va_arg (al, gchar *);
Packit d345d1
    if (!name)
Packit d345d1
      break;
Packit d345d1
    fatal = va_arg (al, gboolean);
Packit d345d1
  }
Packit d345d1
  va_end (al);
Packit d345d1
}
Packit d345d1
Packit d345d1
static void
Packit d345d1
shell_dbus_init (gboolean replace)
Packit d345d1
{
Packit d345d1
  GDBusConnection *session;
Packit d345d1
  GDBusProxy *bus;
Packit d345d1
  GError *error = NULL;
Packit d345d1
  guint32 request_name_flags;
Packit d345d1
  guint32 request_name_result;
Packit d345d1
Packit d345d1
  session = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
Packit d345d1
Packit d345d1
  if (error) {
Packit d345d1
    g_printerr ("Failed to connect to session bus: %s", error->message);
Packit d345d1
    exit (1);
Packit d345d1
  }
Packit d345d1
Packit d345d1
  bus = g_dbus_proxy_new_sync (session,
Packit d345d1
                               G_DBUS_PROXY_FLAGS_NONE,
Packit d345d1
                               NULL, /* interface info */
Packit d345d1
                               "org.freedesktop.DBus",
Packit d345d1
                               "/org/freedesktop/DBus",
Packit d345d1
                               "org.freedesktop.DBus",
Packit d345d1
                               NULL, /* cancellable */
Packit d345d1
                               &error);
Packit d345d1
Packit d345d1
  if (!bus)
Packit d345d1
    {
Packit d345d1
      g_printerr ("Failed to get a session bus proxy: %s", error->message);
Packit d345d1
      exit (1);
Packit d345d1
    }
Packit d345d1
Packit d345d1
  request_name_flags = G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT;
Packit d345d1
  if (replace)
Packit d345d1
    request_name_flags |= G_BUS_NAME_OWNER_FLAGS_REPLACE;
Packit d345d1
Packit d345d1
  shell_dbus_acquire_name (bus,
Packit d345d1
                           request_name_flags,
Packit d345d1
                           &request_name_result,
Packit d345d1
                           SHELL_DBUS_SERVICE, TRUE);
Packit d345d1
  if (!(request_name_result == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER
Packit d345d1
        || request_name_result == DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER))
Packit d345d1
    {
Packit d345d1
      g_printerr (SHELL_DBUS_SERVICE " already exists on bus and --replace not specified\n");
Packit d345d1
      exit (1);
Packit d345d1
    }
Packit d345d1
Packit d345d1
  /*
Packit d345d1
   * We always specify REPLACE_EXISTING to ensure we kill off
Packit d345d1
   * the existing service if it was running.
Packit d345d1
   */
Packit d345d1
  request_name_flags |= G_BUS_NAME_OWNER_FLAGS_REPLACE;
Packit d345d1
Packit d345d1
  shell_dbus_acquire_names (bus,
Packit d345d1
                            request_name_flags,
Packit d345d1
  /* Also grab org.gnome.Panel to replace any existing panel process */
Packit d345d1
                            "org.gnome.Panel", TRUE,
Packit d345d1
  /* ...and the org.gnome.Magnifier service. */
Packit d345d1
                            MAGNIFIER_DBUS_SERVICE, FALSE,
Packit d345d1
  /* ...and the org.freedesktop.Notifications service. */
Packit d345d1
                            "org.freedesktop.Notifications", FALSE,
Packit d345d1
                            NULL);
Packit d345d1
  g_object_unref (bus);
Packit d345d1
  g_object_unref (session);
Packit d345d1
}
Packit d345d1
Packit d345d1
static void
Packit d345d1
shell_introspection_init (void)
Packit d345d1
{
Packit d345d1
Packit d345d1
  g_irepository_prepend_search_path (MUTTER_TYPELIB_DIR);
Packit d345d1
  g_irepository_prepend_search_path (GNOME_SHELL_PKGLIBDIR);
Packit d345d1
Packit d345d1
  /* We need to explicitly add the directories where the private libraries are
Packit d345d1
   * installed to the GIR's library path, so that they can be found at runtime
Packit d345d1
   * when linking using DT_RUNPATH (instead of DT_RPATH), which is the default
Packit d345d1
   * for some linkers (e.g. gold) and in some distros (e.g. Debian).
Packit d345d1
   */
Packit d345d1
  g_irepository_prepend_library_path (MUTTER_TYPELIB_DIR);
Packit d345d1
  g_irepository_prepend_library_path (GNOME_SHELL_PKGLIBDIR);
Packit d345d1
}
Packit d345d1
Packit d345d1
static void
Packit d345d1
shell_fonts_init (void)
Packit d345d1
{
Packit d345d1
  CoglPangoFontMap *fontmap;
Packit d345d1
Packit d345d1
  /* Disable text mipmapping; it causes problems on pre-GEM Intel
Packit d345d1
   * drivers and we should just be rendering text at the right
Packit d345d1
   * size rather than scaling it. If we do effects where we dynamically
Packit d345d1
   * zoom labels, then we might want to reconsider.
Packit d345d1
   */
Packit d345d1
  fontmap = COGL_PANGO_FONT_MAP (clutter_get_font_map ());
Packit d345d1
  cogl_pango_font_map_set_use_mipmapping (fontmap, FALSE);
Packit d345d1
}
Packit d345d1
Packit d345d1
static void
Packit d345d1
malloc_statistics_callback (ShellPerfLog *perf_log,
Packit d345d1
                            gpointer      data)
Packit d345d1
{
Packit d345d1
#ifdef HAVE_MALLINFO
Packit d345d1
  struct mallinfo info = mallinfo ();
Packit d345d1
Packit d345d1
  shell_perf_log_update_statistic_i (perf_log,
Packit d345d1
                                     "malloc.arenaSize",
Packit d345d1
                                     info.arena);
Packit d345d1
  shell_perf_log_update_statistic_i (perf_log,
Packit d345d1
                                     "malloc.mmapSize",
Packit d345d1
                                     info.hblkhd);
Packit d345d1
  shell_perf_log_update_statistic_i (perf_log,
Packit d345d1
                                     "malloc.usedSize",
Packit d345d1
                                     info.uordblks);
Packit d345d1
#endif
Packit d345d1
}
Packit d345d1
Packit d345d1
static void
Packit d345d1
shell_perf_log_init (void)
Packit d345d1
{
Packit d345d1
  ShellPerfLog *perf_log = shell_perf_log_get_default ();
Packit d345d1
Packit d345d1
  /* For probably historical reasons, mallinfo() defines the returned values,
Packit d345d1
   * even those in bytes as int, not size_t. We're determined not to use
Packit d345d1
   * more than 2G of malloc'ed memory, so are OK with that.
Packit d345d1
   */
Packit d345d1
  shell_perf_log_define_statistic (perf_log,
Packit d345d1
                                   "malloc.arenaSize",
Packit d345d1
                                   "Amount of memory allocated by malloc() with brk(), in bytes",
Packit d345d1
                                   "i");
Packit d345d1
  shell_perf_log_define_statistic (perf_log,
Packit d345d1
                                   "malloc.mmapSize",
Packit d345d1
                                   "Amount of memory allocated by malloc() with mmap(), in bytes",
Packit d345d1
                                   "i");
Packit d345d1
  shell_perf_log_define_statistic (perf_log,
Packit d345d1
                                   "malloc.usedSize",
Packit d345d1
                                   "Amount of malloc'ed memory currently in use",
Packit d345d1
                                   "i");
Packit d345d1
Packit d345d1
  shell_perf_log_add_statistics_callback (perf_log,
Packit d345d1
                                          malloc_statistics_callback,
Packit d345d1
                                          NULL, NULL);
Packit d345d1
}
Packit d345d1
Packit d345d1
static void
Packit d345d1
shell_a11y_init (void)
Packit d345d1
{
Packit d345d1
  cally_accessibility_init ();
Packit d345d1
Packit d345d1
  if (clutter_get_accessibility_enabled () == FALSE)
Packit d345d1
    {
Packit d345d1
      g_warning ("Accessibility: clutter has no accessibility enabled"
Packit d345d1
                 " skipping the atk-bridge load");
Packit d345d1
    }
Packit d345d1
  else
Packit d345d1
    {
Packit d345d1
      atk_bridge_adaptor_init (NULL, NULL);
Packit d345d1
    }
Packit d345d1
}
Packit d345d1
Packit d345d1
static void
Packit d345d1
shell_init_debug (const char *debug_env)
Packit d345d1
{
Packit d345d1
  static const GDebugKey keys[] = {
Packit d345d1
    { "backtrace-warnings", SHELL_DEBUG_BACKTRACE_WARNINGS },
Packit d345d1
    { "backtrace-segfaults", SHELL_DEBUG_BACKTRACE_SEGFAULTS },
Packit d345d1
  };
Packit d345d1
Packit d345d1
  _shell_debug = g_parse_debug_string (debug_env, keys,
Packit d345d1
                                       G_N_ELEMENTS (keys));
Packit d345d1
}
Packit d345d1
Packit d345d1
static void
Packit d345d1
default_log_handler (const char     *log_domain,
Packit d345d1
                     GLogLevelFlags  log_level,
Packit d345d1
                     const char     *message,
Packit d345d1
                     gpointer        data)
Packit d345d1
{
Packit d345d1
  GTimeVal now;
Packit d345d1
Packit d345d1
  g_get_current_time (&now;;
Packit d345d1
Packit d345d1
  if (!log_domain || !g_str_has_prefix (log_domain, "tp-glib"))
Packit d345d1
    g_log_default_handler (log_domain, log_level, message, data);
Packit d345d1
Packit d345d1
  /* Filter out Gjs logs, those already have the stack */
Packit d345d1
  if (log_domain && strcmp (log_domain, "Gjs") == 0)
Packit d345d1
    return;
Packit d345d1
Packit d345d1
  if ((_shell_debug & SHELL_DEBUG_BACKTRACE_WARNINGS) &&
Packit d345d1
      ((log_level & G_LOG_LEVEL_CRITICAL) ||
Packit d345d1
       (log_level & G_LOG_LEVEL_WARNING)))
Packit d345d1
    gjs_dumpstack ();
Packit d345d1
}
Packit d345d1
Packit d345d1
static void
Packit d345d1
shut_up (const char     *domain,
Packit d345d1
         GLogLevelFlags  level,
Packit d345d1
         const char     *message,
Packit d345d1
         gpointer        user_data)
Packit d345d1
{
Packit d345d1
}
Packit d345d1
Packit d345d1
static void
Packit d345d1
dump_gjs_stack_alarm_sigaction (int signo)
Packit d345d1
{
Packit d345d1
  g_log_set_default_handler (g_log_default_handler, NULL);
Packit d345d1
  g_warning ("Failed to dump Javascript stack, got stuck");
Packit d345d1
  g_log_set_default_handler (default_log_handler, NULL);
Packit d345d1
Packit d345d1
  raise (caught_signal);
Packit d345d1
}
Packit d345d1
Packit d345d1
static void
Packit d345d1
dump_gjs_stack_on_signal_handler (int signo)
Packit d345d1
{
Packit d345d1
  struct sigaction sa = { 0 };
Packit d345d1
  gsize i;
Packit d345d1
Packit d345d1
  /* Ignore all the signals starting this point, a part the one we'll raise
Packit d345d1
   * (which is implicitly ignored here through SA_RESETHAND), this is needed
Packit d345d1
   * not to get this handler being called by other signals that we were
Packit d345d1
   * tracking and that might be emitted by code called starting from now.
Packit d345d1
   */
Packit d345d1
  for (i = 0; i < G_N_ELEMENTS (_tracked_signals); ++i)
Packit d345d1
    {
Packit d345d1
      if (_tracked_signals[i] && i != signo)
Packit d345d1
        signal (i, SIG_IGN);
Packit d345d1
    }
Packit d345d1
Packit d345d1
  /* Waiting at least 5 seconds for the dumpstack, if it fails, we raise the error */
Packit d345d1
  caught_signal = signo;
Packit d345d1
  sa.sa_handler = dump_gjs_stack_alarm_sigaction;
Packit d345d1
  sigemptyset (&sa.sa_mask);
Packit d345d1
  sigaction (SIGALRM, &sa, NULL);
Packit d345d1
Packit d345d1
  alarm (5);
Packit d345d1
  gjs_dumpstack ();
Packit d345d1
  alarm (0);
Packit d345d1
Packit d345d1
  raise (signo);
Packit d345d1
}
Packit d345d1
Packit d345d1
static void
Packit d345d1
dump_gjs_stack_on_signal (int signo)
Packit d345d1
{
Packit d345d1
  struct sigaction sa = { 0 };
Packit d345d1
Packit d345d1
  sa.sa_flags   = SA_RESETHAND | SA_NODEFER;
Packit d345d1
  sa.sa_handler = dump_gjs_stack_on_signal_handler;
Packit d345d1
  sigemptyset (&sa.sa_mask);
Packit d345d1
Packit d345d1
  sigaction (signo, &sa, NULL);
Packit d345d1
  _tracked_signals[signo] = TRUE;
Packit d345d1
}
Packit d345d1
Packit d345d1
static gboolean
Packit d345d1
list_modes (const char  *option_name,
Packit d345d1
            const char  *value,
Packit d345d1
            gpointer     data,
Packit d345d1
            GError     **error)
Packit d345d1
{
Packit d345d1
  ShellGlobal *global;
Packit d345d1
  GjsContext *context;
Packit d345d1
  const char *script;
Packit d345d1
  int status;
Packit d345d1
Packit d345d1
  /* Many of our imports require global to be set, so rather than
Packit d345d1
   * tayloring our imports carefully here to avoid that dependency,
Packit d345d1
   * we just set it.
Packit d345d1
   * ShellGlobal has some GTK+ dependencies, so initialize GTK+; we
Packit d345d1
   * don't really care if it fails though (e.g. when running from a tty),
Packit d345d1
   * so we mute all warnings */
Packit d345d1
  g_log_set_default_handler (shut_up, NULL);
Packit d345d1
  gtk_init_check (NULL, NULL);
Packit d345d1
Packit d345d1
  _shell_global_init (NULL);
Packit d345d1
  global = shell_global_get ();
Packit d345d1
  context = _shell_global_get_gjs_context (global);
Packit d345d1
Packit d345d1
  shell_introspection_init ();
Packit d345d1
Packit d345d1
  script = "imports.ui.environment.init();"
Packit d345d1
           "imports.ui.sessionMode.listModes();";
Packit d345d1
  if (!gjs_context_eval (context, script, -1, "<main>", &status, NULL))
Packit d345d1
      g_message ("Retrieving list of available modes failed.");
Packit d345d1
Packit d345d1
  g_object_unref (context);
Packit d345d1
  exit (status);
Packit d345d1
}
Packit d345d1
Packit d345d1
static gboolean
Packit d345d1
print_version (const gchar    *option_name,
Packit d345d1
               const gchar    *value,
Packit d345d1
               gpointer        data,
Packit d345d1
               GError        **error)
Packit d345d1
{
Packit d345d1
  g_print ("GNOME Shell %s\n", VERSION);
Packit d345d1
  exit (0);
Packit d345d1
}
Packit d345d1
Packit d345d1
GOptionEntry gnome_shell_options[] = {
Packit d345d1
  {
Packit d345d1
    "version", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
Packit d345d1
    print_version,
Packit d345d1
    N_("Print version"),
Packit d345d1
    NULL
Packit d345d1
  },
Packit d345d1
  {
Packit d345d1
    "gdm-mode", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE,
Packit d345d1
    &is_gdm_mode,
Packit d345d1
    N_("Mode used by GDM for login screen"),
Packit d345d1
    NULL
Packit d345d1
  },
Packit d345d1
  {
Packit d345d1
    "mode", 0, 0, G_OPTION_ARG_STRING,
Packit d345d1
    &session_mode,
Packit d345d1
    N_("Use a specific mode, e.g. “gdm” for login screen"),
Packit d345d1
    "MODE"
Packit d345d1
  },
Packit d345d1
  {
Packit d345d1
    "list-modes", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
Packit d345d1
    list_modes,
Packit d345d1
    N_("List possible modes"),
Packit d345d1
    NULL
Packit d345d1
  },
Packit d345d1
  { NULL }
Packit d345d1
};
Packit d345d1
Packit d345d1
int
Packit d345d1
main (int argc, char **argv)
Packit d345d1
{
Packit d345d1
  GOptionContext *ctx;
Packit d345d1
  GError *error = NULL;
Packit d345d1
  int ecode;
Packit d345d1
Packit d345d1
  bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
Packit d345d1
  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
Packit d345d1
  textdomain (GETTEXT_PACKAGE);
Packit d345d1
Packit d345d1
  session_mode = (char *) g_getenv ("GNOME_SHELL_SESSION_MODE");
Packit d345d1
Packit d345d1
  ctx = meta_get_option_context ();
Packit d345d1
  g_option_context_add_main_entries (ctx, gnome_shell_options, GETTEXT_PACKAGE);
Packit d345d1
  g_option_context_add_group (ctx, g_irepository_get_option_group ());
Packit d345d1
  if (!g_option_context_parse (ctx, &argc, &argv, &error))
Packit d345d1
    {
Packit d345d1
      g_printerr ("%s: %s\n", argv[0], error->message);
Packit d345d1
      exit (1);
Packit d345d1
    }
Packit d345d1
Packit d345d1
  g_option_context_free (ctx);
Packit d345d1
Packit d345d1
  meta_plugin_manager_set_plugin_type (gnome_shell_plugin_get_type ());
Packit d345d1
Packit d345d1
  meta_set_wm_name (WM_NAME);
Packit d345d1
  meta_set_gnome_wm_keybindings (GNOME_WM_KEYBINDINGS);
Packit d345d1
Packit d345d1
  /* Prevent meta_init() from causing gtk to load the atk-bridge*/
Packit d345d1
  g_setenv ("NO_AT_BRIDGE", "1", TRUE);
Packit d345d1
  meta_init ();
Packit d345d1
  g_unsetenv ("NO_AT_BRIDGE");
Packit d345d1
Packit d345d1
  /* FIXME: Add gjs API to set this stuff and don't depend on the
Packit d345d1
   * environment.  These propagate to child processes.
Packit d345d1
   */
Packit d345d1
  g_setenv ("GJS_DEBUG_OUTPUT", "stderr", TRUE);
Packit d345d1
  g_setenv ("GJS_DEBUG_TOPICS", "JS ERROR;JS LOG", TRUE);
Packit d345d1
Packit d345d1
  shell_init_debug (g_getenv ("SHELL_DEBUG"));
Packit d345d1
Packit d345d1
  shell_dbus_init (meta_get_replace_current_wm ());
Packit d345d1
  shell_a11y_init ();
Packit d345d1
  shell_perf_log_init ();
Packit d345d1
  shell_introspection_init ();
Packit d345d1
  shell_fonts_init ();
Packit d345d1
Packit d345d1
  g_log_set_default_handler (default_log_handler, NULL);
Packit d345d1
Packit d345d1
  /* Initialize the global object */
Packit d345d1
  if (session_mode == NULL)
Packit d345d1
    session_mode = is_gdm_mode ? (char *)"gdm" : (char *)"user";
Packit d345d1
Packit d345d1
  _shell_global_init ("session-mode", session_mode, NULL);
Packit d345d1
Packit d345d1
  dump_gjs_stack_on_signal (SIGABRT);
Packit d345d1
  dump_gjs_stack_on_signal (SIGFPE);
Packit d345d1
  dump_gjs_stack_on_signal (SIGIOT);
Packit d345d1
  dump_gjs_stack_on_signal (SIGTRAP);
Packit d345d1
Packit d345d1
  if ((_shell_debug & SHELL_DEBUG_BACKTRACE_SEGFAULTS))
Packit d345d1
    {
Packit d345d1
      dump_gjs_stack_on_signal (SIGBUS);
Packit d345d1
      dump_gjs_stack_on_signal (SIGSEGV);
Packit d345d1
    }
Packit d345d1
Packit d345d1
  ecode = meta_run ();
Packit d345d1
Packit d345d1
  g_debug ("Doing final cleanup");
Packit d345d1
  _shell_global_destroy_gjs_context (shell_global_get ());
Packit d345d1
  g_object_unref (shell_global_get ());
Packit d345d1
Packit d345d1
  return ecode;
Packit d345d1
}