From bf56ccb8eb117615f6b5a7d166325be91279b790 Mon Sep 17 00:00:00 2001 From: Window Maker Date: Sun, 24 May 2026 09:45:09 +0200 Subject: [PATCH] wayland(WIP): reorder unref in wl_frame_configure; add diagnostics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Speculative fix for double-free crash when right-clicking a window titlebar to open the window menu (WMaker's Options cascade brother realize). Stack trace shows pixman_image_unref crashing with 'double free or corruption (out)' on a freshly-created 1x10 image. This commit: * Saves old_image, creates new fb->image, updates metadata, notifies wlroots, THEN unrefs old_image — so wlroots' begin_data_ptr_access only ever sees the new image during the resize transition. * Adds wwarning logging in wl_frame_configure and the buffer destroy callback to catch the crash sequence. Diagnostics will be removed once the root cause is fixed. --- src/backend/wayland/wl_backend.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/backend/wayland/wl_backend.c b/src/backend/wayland/wl_backend.c index 898f9f7..fd8ec51 100644 --- a/src/backend/wayland/wl_backend.c +++ b/src/backend/wayland/wl_backend.c @@ -3986,6 +3986,7 @@ wl_show_crash_dialog(int sig) static void frame_buf_destroy(struct wlr_buffer *wlr_buf) { struct wl_frame_buf *fb = wl_container_of(wlr_buf, fb, base); + wwarning("FBDESTROY: id=0x%lx fb=%p fb->image=%p", fb->id, (void*)fb, fb->image); if (fb->image) pixman_image_unref(fb->image); wfree(fb); @@ -4356,10 +4357,15 @@ wl_frame_configure(WNativeWindow win, int x, int y, int width, int height) /* Resize: reallocate the pixman image if dimensions changed. */ if (width > 0 && height > 0 && (width != fb->width || height != fb->height)) { - if (fb->image) - pixman_image_unref(fb->image); + wwarning("FCFG: id=0x%lx fb->image=%p old_size=%dx%d new_size=%dx%d " + "scene_buf=%p tree=%p parent_id=0x%lx", + fb->id, fb->image, fb->width, fb->height, width, height, + fb->scene_buf, fb->tree, fb->parent_id); + pixman_image_t *old_image = fb->image; fb->image = pixman_image_create_bits(PIXMAN_a8r8g8b8, width, height, NULL, 0); + /* Update fb metadata BEFORE notifying wlroots so it sees the + * new size when accessing the buffer. */ fb->width = width; fb->height = height; fb->base.width = width; @@ -4369,6 +4375,11 @@ wl_frame_configure(WNativeWindow win, int x, int y, int width, int height) * the old size would miss this scene_buf. */ if (fb->scene_buf) wlr_scene_buffer_set_dest_size(fb->scene_buf, width, height); + /* Now drop the old image — wlroots will not access it again + * because we already pointed it to the new one above (via + * fb->image which is what begin_data_ptr_access reads). */ + if (old_image) + pixman_image_unref(old_image); } /* Update absolute position tracking — recursively for all descendants. */