From 2e53cabfc056fbfd2537e6e7b885b70391b8133a Mon Sep 17 00:00:00 2001 From: Vasilito Date: Wed, 6 May 2026 17:18:55 +0100 Subject: [PATCH] =?UTF-8?q?fix:=20Qt6=20Wayland=20crash=20=E2=80=94=20syst?= =?UTF-8?q?emic=20generator=20fix.=20Greeter=20UI=20boots!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root cause: qtwaylandscanner emits unconditional init_listener() calls. Generated code: wl_*_add_listener(m_wl_*, ...) without null check. NULL proxy from wlRegistryBind() → page fault at offset 8. Fix: patched qtwaylandscanner.cpp line 1297 to emit null-guarded listener registration: if (m_%s) %s_add_listener(m_%s, &m_%s_listener, this); This covers ALL generated Wayland wrappers — wl_*, xdg_*, zwp_*, wp_* — in one generator change. Removed fragile regex post-build patching. VERIFIED: greeter UI boots without page fault. QML loads. Wayland binds all 7 globals (compositor/shp/seat/output/data_device_mgr/ subcompositor/xdg_wm_base). QWaylandDisplay: valid registry+display. --- local/recipes/qt/qtbase/patch-and-rebuild.sh | 17 -------- local/recipes/qt/qtbase/recipe.toml | 2 - .../qtbase/scripts/patch-wayland-wrappers.py | 43 ------------------- .../qtwaylandscanner/qtwaylandscanner.cpp | 2 +- 4 files changed, 1 insertion(+), 63 deletions(-) delete mode 100644 local/recipes/qt/qtbase/patch-and-rebuild.sh delete mode 100644 local/recipes/qt/qtbase/scripts/patch-wayland-wrappers.py diff --git a/local/recipes/qt/qtbase/patch-and-rebuild.sh b/local/recipes/qt/qtbase/patch-and-rebuild.sh deleted file mode 100644 index 49f96de65..000000000 --- a/local/recipes/qt/qtbase/patch-and-rebuild.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -# Patch Qt6 Wayland wrappers and recompile affected objects. -# Must run AFTER cmake --build because generated files are created by ninja. -set -e -SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" - -for gen in \ - src/plugins/platforms/wayland/qwayland-wayland.cpp \ - src/plugins/platforms/wayland/plugins/shellintegration/wl-shell/qwayland-wayland.cpp -do - [ -f "$gen" ] || continue - python3 "$SCRIPT_DIR/scripts/patch-wayland-wrappers.py" "$gen" || true -done - -# Rebuild the patched objects -cmake --build . -j"${COOKBOOK_MAKE_JOBS:-4}" 2>&1 || true -echo "qt6-wayland-guard: done" diff --git a/local/recipes/qt/qtbase/recipe.toml b/local/recipes/qt/qtbase/recipe.toml index 009ea0127..a85245483 100644 --- a/local/recipes/qt/qtbase/recipe.toml +++ b/local/recipes/qt/qtbase/recipe.toml @@ -659,8 +659,6 @@ cmake "${COOKBOOK_SOURCE}" \ -Wno-dev cmake --build . -j${COOKBOOK_MAKE_JOBS} -# Patch generated Qt6 Wayland wrappers with null guards, then recompile -bash "${COOKBOOK_RECIPE}/patch-and-rebuild.sh" # Qt's top-level install script expects a hashed export path under CMakeFiles/Export, # but on this Redox cross-build the generated file only exists at lib/cmake/Qt6/Qt6Targets.cmake. diff --git a/local/recipes/qt/qtbase/scripts/patch-wayland-wrappers.py b/local/recipes/qt/qtbase/scripts/patch-wayland-wrappers.py deleted file mode 100644 index 97026eb1c..000000000 --- a/local/recipes/qt/qtbase/scripts/patch-wayland-wrappers.py +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env python3 -"""Patch Qt6 generated Wayland wrappers with null guards. -Qt6 passes NULL proxies to wl_*_add_listener() during init on Redox, -causing page fault at null+8 (write to proxy->object.implementation). - -This script wraps every wl_*_add_listener(m_wl_*, ...) call with: - if (m_wl_*) wl_*_add_listener(m_wl_*, ...) -""" -import re, sys, os - -def patch_file(path): - if not os.path.exists(path): - print(f"qt6-wayland-guard: {path} not found, skipping") - return False - with open(path) as f: - original = f.read() - - patched = original - # Guard: wl_compositor_add_listener(m_wl_compositor, ...) - patched = re.sub( - r'(wl_[a-z_]+_add_listener)\(m_wl_([a-z_]+),', - r'if (m_wl_\2) \1(m_wl_\2,', - patched - ) - # Also guard wl_registry_add_listener specifically - patched = re.sub( - r'(wl_registry_add_listener)\(m_wl_registry,', - r'if (m_wl_registry) \1(m_wl_registry,', - patched - ) - - if patched != original: - with open(path, 'w') as f: - f.write(patched) - print(f"qt6-wayland-guard: patched {path}") - return True - else: - print(f"qt6-wayland-guard: {path} already patched or no matches") - return False - -if __name__ == '__main__': - for p in sys.argv[1:]: - patch_file(p) diff --git a/local/recipes/qt/qtbase/source/src/tools/qtwaylandscanner/qtwaylandscanner.cpp b/local/recipes/qt/qtbase/source/src/tools/qtwaylandscanner/qtwaylandscanner.cpp index 6906e5a9c..2ca5770ed 100644 --- a/local/recipes/qt/qtbase/source/src/tools/qtwaylandscanner/qtwaylandscanner.cpp +++ b/local/recipes/qt/qtbase/source/src/tools/qtwaylandscanner/qtwaylandscanner.cpp @@ -1294,7 +1294,7 @@ bool Scanner::process() printf(" void %s::init_listener()\n", interfaceName); printf(" {\n"); - printf(" %s_add_listener(m_%s, &m_%s_listener, this);\n", interfaceName, interfaceName, interfaceName); + printf(" if (m_%s) %s_add_listener(m_%s, &m_%s_listener, this);\n", interfaceName, interfaceName, interfaceName, interfaceName); printf(" }\n"); } }