-
Notifications
You must be signed in to change notification settings - Fork 115
Crash: XDamageCreate on already-destroyed window causes BadDrawable fatal error #807
Description
Summary
Muffin crashes with a fatal BadDrawable X error when a client rapidly creates and destroys override-redirect windows. The crash originates in create_damage() in src/compositor/meta-surface-actor-x11.c, where XDamageCreate is called without an X error trap.
Steps to Reproduce
- Run an application under Wine 9.0 that rapidly creates/destroys override-redirect X11 windows (e.g. Altium Designer entering placement mode for pins, tracks, or lines)
- Muffin crashes, all window decorations disappear, keyboard shortcuts stop working, no input possible in any window
- Session manager tries to restart Cinnamon but fails ("respawning too quickly")
Error Output
(cinnamon:17468): Gdk-WARNING **: The program 'cinnamon' received an X Window System error.
The error was 'BadDrawable (invalid Pixmap or Window parameter)'.
(Details: serial 5002 error_code 9 request_code 143 (DAMAGE) minor_code 1)
Also observed before the crash:
Window manager warning: WM_TRANSIENT_FOR window 0x50000c1 for 0x50000c4 window
override-redirect is an override-redirect window and this is not correct according
to the standard, so we'll fallback to the first non-override-redirect window 0x500004c.
Root Cause
In src/compositor/meta-surface-actor-x11.c, the create_damage() function (line 347) calls XDamageCreate without an X error trap:
static void
create_damage (MetaSurfaceActorX11 *self)
{
Display *xdisplay = meta_x11_display_get_xdisplay (self->display->x11_display);
Window xwindow = meta_window_x11_get_toplevel_xwindow (self->window);
self->damage = XDamageCreate (xdisplay, xwindow, XDamageReportBoundingBox);
}When a client destroys a window between the time Muffin receives the MapNotify event and the time it calls XDamageCreate, the X server returns BadDrawable, which is treated as a fatal error and crashes Cinnamon.
Notably, XDamageDestroy in the same file (line 82-85) is already protected with meta_x11_error_trap_push/pop:
meta_x11_error_trap_push (display->x11_display);
XDamageDestroy (xdisplay, self->damage);
self->damage = None;
meta_x11_error_trap_pop (display->x11_display);Proposed Fix
Wrap XDamageCreate with the same error trap pattern:
--- a/src/compositor/meta-surface-actor-x11.c
+++ b/src/compositor/meta-surface-actor-x11.c
@@ -349,7 +349,9 @@ create_damage (MetaSurfaceActorX11 *self)
Display *xdisplay = meta_x11_display_get_xdisplay (self->display->x11_display);
Window xwindow = meta_window_x11_get_toplevel_xwindow (self->window);
+ meta_x11_error_trap_push (self->display->x11_display);
self->damage = XDamageCreate (xdisplay, xwindow, XDamageReportBoundingBox);
+ meta_x11_error_trap_pop (self->display->x11_display);
}This is a minimal, safe change — if the window no longer exists, the error is silently ignored and self->damage remains unset. This is the correct behavior since there is nothing to track damage on for a destroyed window.
Environment
- Muffin: 6.6.3+zena
- Cinnamon: Linux Mint 22
- Kernel: 6.17.0-14-generic
- GPU: AMD RDNA4 (amdgpu)
- Trigger application: Wine 9.0 running Altium Designer 16 (but any application rapidly creating/destroying override-redirect windows could trigger this)
Testing
The fix has been locally compiled and tested. With the patched libmuffin.so.0.0.0, the crash no longer occurs — Altium Designer placement operations work without affecting Cinnamon stability.