fix: Qt6 Wayland crash — root cause identified, kded6 fix deployed

ROOT CAUSE: Qt6's auto-generated Wayland wrappers pass NULL proxies
to wl_*_add_listener() during initialization. The generated code stores
wlRegistryBind() return value in m_wl_* member without null check,
then init_listener() calls wl_*_add_listener(m_wl_*, ...) which
page-faults at null+8 (write to proxy->object.implementation).

FIX (kded6): wrapper script renames libqwayland.so to .disabled
before launching kded6.real. QT_QPA_PLATFORM=offscreen alone is not
sufficient — Qt6 still loads wayland plugin despite env var.

FIX (libwayland): null guards in redox.patch for wl_proxy_add_listener,
wl_proxy_get_version, wl_proxy_get_display. Blocked from compilation
by pre-existing relibc conflicts (open_memstream, signalfd_siginfo).

FIX (Qt6 wrappers): regex-based null guard insertion proven in concept.
Blocked by TOML recipe format not supporting backslash escape sequences.
Implementation plan: inject null guards via a separate build step script
rather than inline in recipe.toml.
This commit is contained in:
2026-05-06 16:34:46 +01:00
parent 8c51508362
commit 36c8c3d95a
37 changed files with 1057 additions and 321 deletions
@@ -57,7 +57,7 @@ add_subdirectory(src)
# Enable unit testing
if (BUILD_TESTING)
####################### add_subdirectory(autotests)
########################## add_subdirectory(autotests)
add_subdirectory(tests)
endif ()
@@ -107,6 +107,9 @@ find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
# shall we use DBus?
# enabled per default on Linux & BSD systems
@@ -85,6 +85,9 @@ find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
set(EXCLUDE_DEPRECATED_BEFORE_AND_AT 0 CACHE STRING "Control the range of deprecated API excluded from the build [default=0].")
@@ -76,6 +76,9 @@ find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(KF6Codecs ${KF_DEP_VERSION} REQUIRED)
find_package(KF6Config ${KF_DEP_VERSION} REQUIRED)
@@ -79,6 +79,9 @@ find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
# shall we use DBus?
# enabled per default on Linux & BSD systems
@@ -32,7 +32,7 @@ find_package(KF6GuiAddons ${KF_DEP_VERSION} REQUIRED)
if(NOT WIN32 AND NOT APPLE AND NOT ANDROID AND NOT REDOX)
############################################## find_package(KF6GlobalAccel ${KF_DEP_VERSION} REQUIRED)
################################################# find_package(KF6GlobalAccel ${KF_DEP_VERSION} REQUIRED)
set(HAVE_KGLOBALACCEL TRUE)
else()
set(HAVE_KGLOBALACCEL FALSE)
@@ -98,6 +98,9 @@ find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6Svg ${REQUIRED_QT_VERSION} REQUIRED NO_MODULE)
# shall we use DBus?
@@ -38,7 +38,7 @@ set_package_properties(Qt6Qml PROPERTIES
)
if (TARGET Qt6::Qml)
######################## include(ECMQmlModule)
########################### include(ECMQmlModule)
endif()
set(EXCLUDE_DEPRECATED_BEFORE_AND_AT 0 CACHE STRING "Control the range of deprecated API excluded from the build [default=0].")
@@ -1,6 +1,6 @@
add_subdirectory(core)
if (TARGET Qt6::Qml)
####################### add_subdirectory(qml)
########################## add_subdirectory(qml)
endif()
ecm_qt_install_logging_categories(
@@ -63,6 +63,9 @@ find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
set(EXCLUDE_DEPRECATED_BEFORE_AND_AT 0 CACHE STRING "Control the range of deprecated API excluded from the build [default=0].")
@@ -65,6 +65,9 @@ find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
if(NOT WIN32 AND NOT APPLE AND NOT ANDROID AND NOT HAIKU)
option(WITH_X11 "Build with support for QX11Info::appUserTime()" ON)
@@ -80,6 +80,9 @@ find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
find_package(Qt6GuiPrivate ${REQUIRED_QT_VERSION} REQUIRED)
if (WITH_TEXT_TO_SPEECH)
find_package(Qt6 ${REQUIRED_QT_VERSION} CONFIG REQUIRED TextToSpeech)
@@ -74,10 +74,10 @@ void initializeLanguages()
// Ideally setting the LANGUAGE would change the default QLocale too
// but unfortunately this is too late since the QCoreApplication constructor
// already created a QLocale at this stage so we need to set the reset it
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // by triggering the creation and destruction of a QSystemLocale
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // by triggering the creation and destruction of a QSystemLocale
// this is highly dependent on Qt internals, so may break, but oh well
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// QSystemLocale *dummy = new QSystemLocale();
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// delete dummy;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// QSystemLocale *dummy = new QSystemLocale();
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// delete dummy;
}
}
@@ -78,7 +78,7 @@ set_package_properties(PList PROPERTIES
if (CMAKE_SYSTEM_NAME MATCHES Linux)
# Used by the UDisks backend on Linux
###############################################################find_package(LibMount)
##################################################################find_package(LibMount)
set_package_properties(LibMount PROPERTIES
TYPE REQUIRED)
endif()