forked from qt-creator/qt-creator
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:
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user