wayland(WIP): reorder unref in wl_frame_configure; add diagnostics

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.
This commit is contained in:
Window Maker 2026-05-24 09:45:09 +02:00
parent eeb161c616
commit bf56ccb8eb
1 changed files with 13 additions and 2 deletions

View File

@ -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. */