From 6e8dcbcfd23414d0d6d9be659ce5a7c6d2de049a Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 1 Nov 2021 13:18:43 +0100 Subject: Fix a crash when modifying pro file In some unlikely case it may happen that between finished() signal is emitted by a watcher and when the queued handler is being called, someone could have called CppProjectUpdater::cancel() and delete the watcher immediately. In this case the handler could operate on deleted watcher instance. Add a QPointer in order to guard the watcher inside the queued handler. Amends: e3b639047f6a4a9c042987062bafdbf1726267cb Fixes: QTCREATORBUG-26507 Change-Id: Idb4a953e9017ce672adc64becb3061bd80c8c378 Reviewed-by: Eike Ziller --- src/plugins/cpptools/cppprojectupdater.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/plugins/cpptools/cppprojectupdater.cpp b/src/plugins/cpptools/cppprojectupdater.cpp index f34628af51..61d9443c98 100644 --- a/src/plugins/cpptools/cppprojectupdater.cpp +++ b/src/plugins/cpptools/cppprojectupdater.cpp @@ -93,11 +93,16 @@ void CppProjectUpdater::update(const ProjectUpdateInfo &projectUpdateInfo, // extra compilers for (QPointer compiler : qAsConst(m_extraCompilers)) { if (compiler->isDirty()) { - auto watcher = new QFutureWatcher; + QPointer> watcher = new QFutureWatcher; // queued connection to delay after the extra compiler updated its result contents, // which is also done in the main thread when compiler->run() finished connect(watcher, &QFutureWatcherBase::finished, this, [this, watcher] { + // In very unlikely case the CppProjectUpdater::cancel() could have been + // invoked after posting the finished() signal and before this handler + // gets called. In this case the watcher is already deleted. + if (!watcher) + return; m_projectUpdateFutureInterface->setProgressValue( m_projectUpdateFutureInterface->progressValue() + 1); m_extraCompilersFutureWatchers.remove(watcher); -- cgit v1.2.3