diff options
| author | Vladimir Belyavsky <belyavskyv@gmail.com> | 2026-03-23 11:36:34 +0300 |
|---|---|---|
| committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2026-04-01 02:58:26 +0000 |
| commit | 6cb7ca6b3df86f005b9718263bd66d25b0e3bfe2 (patch) | |
| tree | 3f5a7e310dd0637e5effe31e93437d873d6e7089 | |
| parent | b242282564ebbb6e5870d51d8709dde8e86a685e (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.cpp | 8 | ||||
| -rw-r--r-- | src/quick/scenegraph/qsgthreadedrenderloop.cpp | 1 |
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() |
