aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladimir Belyavsky <belyavskyv@gmail.com>2026-03-23 11:36:34 +0300
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2026-04-01 02:58:26 +0000
commit6cb7ca6b3df86f005b9718263bd66d25b0e3bfe2 (patch)
tree3f5a7e310dd0637e5effe31e93437d873d6e7089
parentb242282564ebbb6e5870d51d8709dde8e86a685e (diff)
Scenegraph: Nullify QQuickWindowPrivate::rhi on RHI destruction6.10
After destroyRhi(), WindowData::rhi and the render thread's local rhi pointer were set to nullptr, but QQuickWindowPrivate::rhi was left dangling in several code paths: - QSGGuiThreadRenderLoop::handleDeviceLoss() - QSGGuiThreadRenderLoop::teardownGraphics() - QSGRenderThread::teardownGraphics() Any code that reads QQuickWindowPrivate::rhi after RHI destruction (e.g. during item reparenting, Loader deactivation, or scene graph re-initialization) could dereference the dangling pointer, leading to use-after-free crashes. Pick-to: 6.8 Change-Id: If4db2c97db4da10e4a419f0a30930ee37120f344 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io> (cherry picked from commit 6a2e413a5aad4044693960b3cf9a4ec308809a94) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> (cherry picked from commit 6b78da362f411315bd766d1ec6789de6b8f55bfd)
-rw-r--r--src/quick/scenegraph/qsgrenderloop.cpp8
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp1
2 files changed, 7 insertions, 2 deletions
diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp
index 319c98ef93..e2a2d458f1 100644
--- a/src/quick/scenegraph/qsgrenderloop.cpp
+++ b/src/quick/scenegraph/qsgrenderloop.cpp
@@ -384,13 +384,15 @@ void QSGGuiThreadRenderLoop::teardownGraphics()
{
for (auto it = m_windows.begin(), itEnd = m_windows.end(); it != itEnd; ++it) {
if (it->rhi) {
- QQuickWindowPrivate::get(it.key())->cleanupNodesOnShutdown();
+ QQuickWindowPrivate *wd = QQuickWindowPrivate::get(it.key());
+ wd->cleanupNodesOnShutdown();
if (it->rc)
it->rc->invalidate();
releaseSwapchain(it.key());
if (it->ownRhi)
QSGRhiSupport::instance()->destroyRhi(it->rhi, {});
it->rhi = nullptr;
+ wd->rhi = nullptr;
}
}
}
@@ -403,7 +405,8 @@ void QSGGuiThreadRenderLoop::handleDeviceLoss()
if (!it->rhi || !it->rhi->isDeviceLost())
continue;
- QQuickWindowPrivate::get(it.key())->cleanupNodesOnShutdown();
+ QQuickWindowPrivate *wd = QQuickWindowPrivate::get(it.key());
+ wd->cleanupNodesOnShutdown();
if (it->rc)
it->rc->invalidate();
@@ -414,6 +417,7 @@ void QSGGuiThreadRenderLoop::handleDeviceLoss()
if (it->ownRhi)
QSGRhiSupport::instance()->destroyRhi(it->rhi, {});
it->rhi = nullptr;
+ wd->rhi = nullptr;
}
}
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
index 4094a9d15c..d0528ac7f3 100644
--- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp
+++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp
@@ -598,6 +598,7 @@ void QSGRenderThread::teardownGraphics()
if (ownRhi)
QSGRhiSupport::instance()->destroyRhi(rhi, {});
rhi = nullptr;
+ wd->rhi = nullptr;
}
void QSGRenderThread::handleDeviceLoss()