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
This commit is contained in:
Daniel van Vugt 2017-10-25 15:42:49 +08:00 committed by Marco Trevisan (Treviño)
parent 01de04d8c9
commit 054c25f693
2 changed files with 33 additions and 12 deletions

View File

@ -50,11 +50,12 @@ typedef struct
char *lock_file; char *lock_file;
int abstract_fd; int abstract_fd;
int unix_fd; int unix_fd;
pid_t pid;
struct wl_client *client; struct wl_client *client;
struct wl_resource *xserver_resource; struct wl_resource *xserver_resource;
char *display_name; char *display_name;
GCancellable *xserver_died_cancellable;
GSubprocess *proc;
GMainLoop *init_loop; GMainLoop *init_loop;
MetaXWaylandSelection *selection_data; MetaXWaylandSelection *selection_data;

View File

@ -392,8 +392,15 @@ xserver_died (GObject *source,
gpointer user_data) gpointer user_data)
{ {
GSubprocess *proc = G_SUBPROCESS (source); 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"); g_error ("X Wayland crashed; aborting");
else else
{ {
@ -508,7 +515,6 @@ meta_xwayland_start (MetaXWaylandManager *manager,
gboolean started = FALSE; gboolean started = FALSE;
g_autoptr(GSubprocessLauncher) launcher = NULL; g_autoptr(GSubprocessLauncher) launcher = NULL;
GSubprocessFlags flags; GSubprocessFlags flags;
GSubprocess *proc;
GError *error = NULL; GError *error = NULL;
if (!choose_xdisplay (manager)) 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_take_fd (launcher, displayfd[1], 6);
g_subprocess_launcher_setenv (launcher, "WAYLAND_SOCKET", "3", TRUE); g_subprocess_launcher_setenv (launcher, "WAYLAND_SOCKET", "3", TRUE);
proc = g_subprocess_launcher_spawn (launcher, &error,
XWAYLAND_PATH, manager->display_name, /* Use the -terminate parameter to ensure that Xwayland exits cleanly
"-rootless", "-noreset", * after the last client disconnects. Fortunately that includes the window
"-listen", "4", * manager so it won't exit prematurely either. This ensures that Xwayland
"-listen", "5", * won't try to reconnect and crash, leaving uninteresting core dumps. We do
"-displayfd", "6", * want core dumps from Xwayland but only if a real bug occurs...
NULL); */
if (!proc) 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); g_error ("Failed to spawn Xwayland: %s", error->message);
goto out; 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); g_unix_fd_add (displayfd[0], G_IO_IN, on_displayfd_ready, manager);
manager->client = wl_client_create (wl_display, xwayland_client_fd[0]); manager->client = wl_client_create (wl_display, xwayland_client_fd[0]);
@ -598,7 +615,10 @@ meta_xwayland_stop (MetaXWaylandManager *manager)
{ {
char path[256]; char path[256];
g_cancellable_cancel (manager->xserver_died_cancellable);
meta_xwayland_shutdown_selection (); 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); snprintf (path, sizeof path, "/tmp/.X11-unix/X%d", manager->display_index);
unlink (path); unlink (path);