C++: Fix crash after triggering completion and closing editor

Fix use-after-free for the following case:
  1. Open an editor
  2. Trigger a long processing completion
     (e.g. simulate with QThread::msleep in
      CppCompletionAssistInterface::getCppSpecifics)
  3. ...and immediately close the editor (e.g. with Ctrl+W)
  4. Wait until it crashes.

The completion thread relied on the BuiltinEditorDocumentParser object,
which is deleted once the editor is closed. Fixed by sharing the
ownership of that object between the *EditorDocumentProcessor and the
completion assist interface.

This case came up when doing tests for the bug report below.

Task-number: QTCREATORBUG-14991
Change-Id: I0b009229e68fc6b7838740858cdc41a32403fe6f
Reviewed-by: David Schulz <david.schulz@theqtcompany.com>
This commit is contained in:
Nikolai Kosjar
2015-09-01 17:34:07 +02:00
parent c504e56d0c
commit 169556db2f
17 changed files with 49 additions and 50 deletions

View File

@@ -94,7 +94,7 @@ ClangEditorDocumentProcessor::ClangEditorDocumentProcessor(
TextEditor::TextDocument *document)
: BaseEditorDocumentProcessor(document)
, m_modelManagerSupport(modelManagerSupport)
, m_parser(document->filePath().toString())
, m_parser(new ClangEditorDocumentParser(document->filePath().toString()))
, m_parserRevision(0)
, m_semanticHighlighter(document)
, m_builtinProcessor(document, /*enableSemanticHighlighter=*/ false)
@@ -114,7 +114,7 @@ ClangEditorDocumentProcessor::ClangEditorDocumentProcessor(
const int firstLine = 1;
const int lastLine = baseTextDocument()->document()->blockCount();
CreateMarkers *createMarkers = CreateMarkers::create(m_parser.semanticMarker(),
CreateMarkers *createMarkers = CreateMarkers::create(m_parser->semanticMarker(),
baseTextDocument()->filePath().toString(),
firstLine, lastLine);
return createMarkers->start();
@@ -169,9 +169,9 @@ CppTools::SemanticInfo ClangEditorDocumentProcessor::recalculateSemanticInfo()
return m_builtinProcessor.recalculateSemanticInfo();
}
CppTools::BaseEditorDocumentParser *ClangEditorDocumentProcessor::parser()
CppTools::BaseEditorDocumentParser::Ptr ClangEditorDocumentProcessor::parser()
{
return &m_parser;
return m_parser;
}
CPlusPlus::Snapshot ClangEditorDocumentProcessor::snapshot()
@@ -196,7 +196,7 @@ ClangEditorDocumentProcessor *ClangEditorDocumentProcessor::get(const QString &f
void ClangEditorDocumentProcessor::updateProjectPartAndTranslationUnitForCompletion()
{
const CppTools::ProjectPart::Ptr projectPart = m_parser.projectPart();
const CppTools::ProjectPart::Ptr projectPart = m_parser->projectPart();
QTC_ASSERT(projectPart, return);
updateTranslationUnitForCompletion(*projectPart.data());
@@ -209,11 +209,11 @@ void ClangEditorDocumentProcessor::onParserFinished()
return;
// Emit ifdefed out blocks
const auto ifdefoutBlocks = toTextEditorBlocks(m_parser.ifdefedOutBlocks());
const auto ifdefoutBlocks = toTextEditorBlocks(m_parser->ifdefedOutBlocks());
emit ifdefedOutBlocksUpdated(revision(), ifdefoutBlocks);
// Emit code warnings
const auto diagnostics = toCppToolsDiagnostics(filePath(), m_parser.diagnostics());
const auto diagnostics = toCppToolsDiagnostics(filePath(), m_parser->diagnostics());
const auto codeWarnings = toTextEditorSelections(diagnostics, textDocument());
emit codeWarningsUpdated(revision(), codeWarnings);