From 889cd056e7c7e95de67e18df9e13244d7c4c14e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Wed, 24 May 2023 15:18:44 +0200 Subject: [PATCH] x11/x11-errors: Use the default error handler when display is destroyed An X11 server connection may still be around when we close the display, and mutter_x_error could be triggered when x11_display has been already destroyed leading to a crash. To prevent this use the default X11 error handler. As per this, also move the ownership of the error traps to x11-errors. See: https://gitlab.gnome.org/GNOME/mutter/-/issues/2835 Part-of: --- src/x11/meta-x11-display-private.h | 2 ++ src/x11/meta-x11-display.c | 3 +-- src/x11/meta-x11-errors.c | 13 +++++++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/x11/meta-x11-display-private.h b/src/x11/meta-x11-display-private.h index 8f9ec1e6e..6822ed4dc 100644 --- a/src/x11/meta-x11-display-private.h +++ b/src/x11/meta-x11-display-private.h @@ -299,4 +299,6 @@ void meta_x11_display_clear_stage_input_region (MetaX11Display *x11_display); void meta_x11_display_init_error_traps (MetaX11Display *x11_display); +void meta_x11_display_destroy_error_traps (MetaX11Display *x11_display); + #endif /* META_X11_DISPLAY_PRIVATE_H */ diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c index a965ef864..e59e02e4b 100644 --- a/src/x11/meta-x11-display.c +++ b/src/x11/meta-x11-display.c @@ -265,6 +265,7 @@ meta_x11_display_dispose (GObject *object) x11_display->xroot = None; } + meta_x11_display_destroy_error_traps (x11_display); if (x11_display->xdisplay) { @@ -284,8 +285,6 @@ meta_x11_display_dispose (GObject *object) g_free (x11_display->screen_name); x11_display->screen_name = NULL; - g_clear_list (&x11_display->error_traps, g_free); - G_OBJECT_CLASS (meta_x11_display_parent_class)->dispose (object); } diff --git a/src/x11/meta-x11-errors.c b/src/x11/meta-x11-errors.c index 51e705ccd..96224ed5f 100644 --- a/src/x11/meta-x11-errors.c +++ b/src/x11/meta-x11-errors.c @@ -205,10 +205,23 @@ delete_outdated_error_traps (MetaX11Display *x11_display) void meta_x11_display_init_error_traps (MetaX11Display *x11_display) { + g_assert (error_x11_display == NULL); error_x11_display = x11_display; XSetErrorHandler (meta_x_error); } +void +meta_x11_display_destroy_error_traps (MetaX11Display *x11_display) +{ + if (error_x11_display == NULL) + return; + + g_assert (error_x11_display == x11_display); + g_clear_list (&x11_display->error_traps, g_free); + error_x11_display = NULL; + XSetErrorHandler (NULL); +} + void meta_x11_error_trap_push (MetaX11Display *x11_display) {