Subject: bug#63589: [PATCH] 29.0.91; crash after creating graphical frames via emacsclient when compiled with cairo-xcb

From: Po Lu <[email-masked]>
Date: Mon, 22 May 2023 10:48:43 +0800

Po Lu <[email-masked]> writes:

> The situation in which this crash occurs is sufficiently uncommon.  It's
> the result of another bug in Emacs, hopefully one that should be safe to
> fix.

Unfortunately, both this crash and its cause (actually, a
RenderBadPicture from a glyph compositing request somewhere within
cairo) are bugs in cairo-xcb itself.  Emacs never allows the display
connection to be closed without dereferencing all Cairo resources
created for that display connection, but Cairo keeps its own references
around.

The only reasonable solution is to disable the use of XCB surfaces by
default.  Is this OK for the release branch?

diff --git a/configure.ac b/configure.ac
index 95167329c28..d7296168ff9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -459,6 +459,7 @@ AC_DEFUN
 OPTION_DEFAULT_ON([lcms2],[don't compile with Little CMS support])
 OPTION_DEFAULT_ON([libsystemd],[don't compile with libsystemd support])
 OPTION_DEFAULT_ON([cairo],[don't compile with Cairo drawing])
+OPTION_DEFAULT_OFF([cairo-xcb], [use XCB surfaces for Cairo support])
 OPTION_DEFAULT_ON([xml2],[don't compile with XML parsing support])
 OPTION_DEFAULT_OFF([imagemagick],[compile with ImageMagick image support])
 OPTION_DEFAULT_ON([native-image-api], [don't use native image APIs (GDI+ on Windows)])
@@ -3571,14 +3572,19 @@ AC_DEFUN
     CAIRO_MODULE="cairo >= $CAIRO_REQUIRED"
     EMACS_CHECK_MODULES([CAIRO], [$CAIRO_MODULE])
     if test $HAVE_CAIRO = yes; then
-      CAIRO_XCB_MODULE="cairo-xcb >= $CAIRO_REQUIRED"
-      EMACS_CHECK_MODULES([CAIRO_XCB], [$CAIRO_XCB_MODULE])
-      if test $HAVE_CAIRO_XCB = yes; then
-	CAIRO_CFLAGS="$CAIRO_CFLAGS $CAIRO_XCB_CFLAGS"
-	CAIRO_LIBS="$CAIRO_LIBS $CAIRO_XCB_LIBS"
-	AC_DEFINE([USE_CAIRO_XCB], [1],
-	  [Define to 1 if cairo XCB surfaces are available.])
-      fi
+      dnl Cairo XCB support is disabled by default, as the Cairo XCB
+      dnl backend itself seems to be buggy: multiple Cairo devices can
+      dnl be created for the same visual on the same connection, and
+      dnl the devices are never destroyed, even when all references go
+      dnl away.
+      AS_IF([test "x$with_cairo_xcb" = "xyes"], [
+	CAIRO_XCB_MODULE="cairo-xcb >= $CAIRO_REQUIRED"
+	EMACS_CHECK_MODULES([CAIRO_XCB], [$CAIRO_XCB_MODULE])
+	AS_IF([test "x$HAVE_CAIRO_XCB" = "xyes"], [
+	  CAIRO_CFLAGS="$CAIRO_CFLAGS $CAIRO_XCB_CFLAGS"
+	  CAIRO_LIBS="$CAIRO_LIBS $CAIRO_XCB_LIBS"
+	  AC_DEFINE([USE_CAIRO_XCB], [1],
+	    [Define to 1 if cairo XCB surfaces are available.])])])
       AC_DEFINE([USE_CAIRO], [1], [Define to 1 if using cairo.])
       CFLAGS="$CFLAGS $CAIRO_CFLAGS"
       LIBS="$LIBS $CAIRO_LIBS"