QmakeProjectManager: Try harder not to access nodes of in-parse project

For extra safety, do not touch the project nodes if any build system of
any build configuration is currently parsing.
This is a bit of a stab in the dark, as I cannot reproduce the crash
described in the linked bug report.

Task-number: QTCREATORBUG-23597
Change-Id: Ie62a94232e89d8fba5866ea3572535e2ab209924
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Christian Kandeler
2020-03-03 14:57:21 +01:00
parent 5683f2df85
commit ae0d2bd1ac
3 changed files with 20 additions and 7 deletions

View File

@@ -320,7 +320,7 @@ bool Project::removeTarget(Target *target)
return true; return true;
} }
QList<Target *> Project::targets() const const QList<Target *> Project::targets() const
{ {
return Utils::toRawPointer<QList>(d->m_targets); return Utils::toRawPointer<QList>(d->m_targets);
} }

View File

@@ -106,7 +106,7 @@ public:
Target *addTargetForKit(Kit *kit); Target *addTargetForKit(Kit *kit);
bool removeTarget(Target *target); bool removeTarget(Target *target);
QList<Target *> targets() const; const QList<Target *> targets() const;
// Note: activeTarget can be 0 (if no targets are defined). // Note: activeTarget can be 0 (if no targets are defined).
Target *activeTarget() const; Target *activeTarget() const;
Target *target(Core::Id id) const; Target *target(Core::Id id) const;

View File

@@ -37,6 +37,7 @@
#include <coreplugin/fileiconprovider.h> #include <coreplugin/fileiconprovider.h>
#include <extensionsystem/pluginmanager.h> #include <extensionsystem/pluginmanager.h>
#include <qtsupport/qtsupportconstants.h> #include <qtsupport/qtsupportconstants.h>
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/target.h> #include <projectexplorer/target.h>
#include <projectexplorer/session.h> #include <projectexplorer/session.h>
@@ -85,12 +86,24 @@ QString ProFileEditorWidget::checkForPrfFile(const QString &baseName) const
{ {
const FilePath projectFile = textDocument()->filePath(); const FilePath projectFile = textDocument()->filePath();
const QmakePriFileNode *projectNode = nullptr; const QmakePriFileNode *projectNode = nullptr;
// FIXME: Remove this check once project nodes are fully "static".
for (const Project * const project : SessionManager::projects()) { for (const Project * const project : SessionManager::projects()) {
if (Target *t = project->activeTarget()) { static const auto isParsing = [](const Project *project) {
if (t->buildSystem()->isParsing()) for (const Target * const t : project->targets()) {
continue; for (const BuildConfiguration * const bc : t->buildConfigurations()) {
if (bc->buildSystem()->isParsing())
return true;
} }
projectNode = dynamic_cast<const QmakePriFileNode *>(project->rootProjectNode() }
return false;
};
if (isParsing(project))
continue;
ProjectNode * const rootNode = project->rootProjectNode();
QTC_ASSERT(rootNode, continue);
projectNode = dynamic_cast<const QmakePriFileNode *>(rootNode
->findProjectNode([&projectFile](const ProjectNode *pn) { ->findProjectNode([&projectFile](const ProjectNode *pn) {
return pn->filePath() == projectFile; return pn->filePath() == projectFile;
})); }));