fix: Qt6 Wayland crash — systemic generator fix. Greeter UI boots!
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.
This commit is contained in:
@@ -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"
|
|
||||||
@@ -659,8 +659,6 @@ cmake "${COOKBOOK_SOURCE}" \
|
|||||||
-Wno-dev
|
-Wno-dev
|
||||||
|
|
||||||
cmake --build . -j${COOKBOOK_MAKE_JOBS}
|
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,
|
# 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.
|
# but on this Redox cross-build the generated file only exists at lib/cmake/Qt6/Qt6Targets.cmake.
|
||||||
|
|||||||
@@ -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)
|
|
||||||
@@ -1294,7 +1294,7 @@ bool Scanner::process()
|
|||||||
|
|
||||||
printf(" void %s::init_listener()\n", interfaceName);
|
printf(" void %s::init_listener()\n", interfaceName);
|
||||||
printf(" {\n");
|
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");
|
printf(" }\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user