From ae0d2bd1ac4f8102be4e76ef6701a253fe6c9bc1 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Tue, 3 Mar 2020 14:57:21 +0100 Subject: [PATCH] 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 --- src/plugins/projectexplorer/project.cpp | 2 +- src/plugins/projectexplorer/project.h | 2 +- .../qmakeprojectmanager/profileeditor.cpp | 23 +++++++++++++++---- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp index f338b3bfafc..e7e6599ed91 100644 --- a/src/plugins/projectexplorer/project.cpp +++ b/src/plugins/projectexplorer/project.cpp @@ -320,7 +320,7 @@ bool Project::removeTarget(Target *target) return true; } -QList Project::targets() const +const QList Project::targets() const { return Utils::toRawPointer(d->m_targets); } diff --git a/src/plugins/projectexplorer/project.h b/src/plugins/projectexplorer/project.h index b93e273a068..b6b65e68893 100644 --- a/src/plugins/projectexplorer/project.h +++ b/src/plugins/projectexplorer/project.h @@ -106,7 +106,7 @@ public: Target *addTargetForKit(Kit *kit); bool removeTarget(Target *target); - QList targets() const; + const QList targets() const; // Note: activeTarget can be 0 (if no targets are defined). Target *activeTarget() const; Target *target(Core::Id id) const; diff --git a/src/plugins/qmakeprojectmanager/profileeditor.cpp b/src/plugins/qmakeprojectmanager/profileeditor.cpp index 3d14ff3d500..a00e26d39e1 100644 --- a/src/plugins/qmakeprojectmanager/profileeditor.cpp +++ b/src/plugins/qmakeprojectmanager/profileeditor.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -85,12 +86,24 @@ QString ProFileEditorWidget::checkForPrfFile(const QString &baseName) const { const FilePath projectFile = textDocument()->filePath(); const QmakePriFileNode *projectNode = nullptr; + + // FIXME: Remove this check once project nodes are fully "static". for (const Project * const project : SessionManager::projects()) { - if (Target *t = project->activeTarget()) { - if (t->buildSystem()->isParsing()) - continue; - } - projectNode = dynamic_cast(project->rootProjectNode() + static const auto isParsing = [](const Project *project) { + for (const Target * const t : project->targets()) { + for (const BuildConfiguration * const bc : t->buildConfigurations()) { + if (bc->buildSystem()->isParsing()) + return true; + } + } + return false; + }; + if (isParsing(project)) + continue; + + ProjectNode * const rootNode = project->rootProjectNode(); + QTC_ASSERT(rootNode, continue); + projectNode = dynamic_cast(rootNode ->findProjectNode([&projectFile](const ProjectNode *pn) { return pn->filePath() == projectFile; }));