summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel van Vugt <daniel.van.vugt@canonical.com>2017-10-25 07:42:49 (GMT)
committerMarco Trevisan (Treviño) <mail@3v1n0.net>2017-10-27 00:50:40 (GMT)
commit054c25f693af579ba3de9b73dad224ce93ba773b (patch)
tree7201a26bf26aee488b21f54af8c93973f213d323
parent01de04d8c91b1be142e06b2203589bfcd9b52e93 (diff)
downloadmutter-054c25f693a.zip
mutter-054c25f693a.tar.xz
wayland: Allow Xwayland to leave core dumps
For historical Xorg-reasons, Xwayland would disable its own core dumps by default. This is a problem because Xwayland crashing is the biggest cause of gnome-shell crashes [1][2], and we still have no idea why due to there being no dumps from Xwayland. So enable core dumping from Xwayland. https://bugzilla.gnome.org/show_bug.cgi?id=789086 [1] https://bugs.launchpad.net/bugs/1505409 [2] https://bugs.launchpad.net/bugs/1556601
-rw-r--r--src/wayland/meta-wayland-private.h3
-rw-r--r--src/wayland/meta-xwayland.c42
2 files changed, 33 insertions, 12 deletions
diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h
index a8c4568..8ff8536 100644
--- a/src/wayland/meta-wayland-private.h
+++ b/src/wayland/meta-wayland-private.h
@@ -50,11 +50,12 @@ typedef struct
char *lock_file;
int abstract_fd;
int unix_fd;
- pid_t pid;
struct wl_client *client;
struct wl_resource *xserver_resource;
char *display_name;
+ GCancellable *xserver_died_cancellable;
+ GSubprocess *proc;
GMainLoop *init_loop;
MetaXWaylandSelection *selection_data;
diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c
index 50cfc7c..a2ff0ea 100644
--- a/src/wayland/meta-xwayland.c
+++ b/src/wayland/meta-xwayland.c
@@ -392,8 +392,15 @@ xserver_died (GObject *source,
gpointer user_data)
{
GSubprocess *proc = G_SUBPROCESS (source);
+ GError *error = NULL;
- if (!g_subprocess_get_successful (proc))
+ if (!g_subprocess_wait_finish (proc, result, &error))
+ {
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ g_error ("Failed to finish waiting for Xwayland: %s", error->message);
+ g_clear_error (&error);
+ }
+ else if (!g_subprocess_get_successful (proc))
g_error ("X Wayland crashed; aborting");
else
{
@@ -508,7 +515,6 @@ meta_xwayland_start (MetaXWaylandManager *manager,
gboolean started = FALSE;
g_autoptr(GSubprocessLauncher) launcher = NULL;
GSubprocessFlags flags;
- GSubprocess *proc;
GError *error = NULL;
if (!choose_xdisplay (manager))
@@ -545,20 +551,31 @@ meta_xwayland_start (MetaXWaylandManager *manager,
g_subprocess_launcher_take_fd (launcher, displayfd[1], 6);
g_subprocess_launcher_setenv (launcher, "WAYLAND_SOCKET", "3", TRUE);
- proc = g_subprocess_launcher_spawn (launcher, &error,
- XWAYLAND_PATH, manager->display_name,
- "-rootless", "-noreset",
- "-listen", "4",
- "-listen", "5",
- "-displayfd", "6",
- NULL);
- if (!proc)
+
+ /* Use the -terminate parameter to ensure that Xwayland exits cleanly
+ * after the last client disconnects. Fortunately that includes the window
+ * manager so it won't exit prematurely either. This ensures that Xwayland
+ * won't try to reconnect and crash, leaving uninteresting core dumps. We do
+ * want core dumps from Xwayland but only if a real bug occurs...
+ */
+ manager->proc = g_subprocess_launcher_spawn (launcher, &error,
+ XWAYLAND_PATH, manager->display_name,
+ "-rootless",
+ "-terminate",
+ "-core",
+ "-listen", "4",
+ "-listen", "5",
+ "-displayfd", "6",
+ NULL);
+ if (!manager->proc)
{
g_error ("Failed to spawn Xwayland: %s", error->message);
goto out;
}
- g_subprocess_wait_async (proc, NULL, xserver_died, NULL);
+ manager->xserver_died_cancellable = g_cancellable_new ();
+ g_subprocess_wait_async (manager->proc, manager->xserver_died_cancellable,
+ xserver_died, NULL);
g_unix_fd_add (displayfd[0], G_IO_IN, on_displayfd_ready, manager);
manager->client = wl_client_create (wl_display, xwayland_client_fd[0]);
@@ -598,7 +615,10 @@ meta_xwayland_stop (MetaXWaylandManager *manager)
{
char path[256];
+ g_cancellable_cancel (manager->xserver_died_cancellable);
meta_xwayland_shutdown_selection ();
+ g_clear_object (&manager->proc);
+ g_clear_object (&manager->xserver_died_cancellable);
snprintf (path, sizeof path, "/tmp/.X11-unix/X%d", manager->display_index);
unlink (path);