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

@@ -426,13 +426,13 @@ AssistInterface *InternalCompletionAssistProvider::createAssistInterface(
{
QTC_ASSERT(textEditorWidget, return 0);
CppModelManager *modelManager = CppModelManager::instance();
return new CppCompletionAssistInterface(filePath,
textEditorWidget,
BuiltinEditorDocumentParser::get(filePath),
languageFeatures,
position,
reason,
modelManager->workingCopy());
CppModelManager::instance()->workingCopy());
}
// -----------------
@@ -2187,11 +2187,11 @@ void CppCompletionAssistInterface::getCppSpecifics() const
return;
m_gotCppSpecifics = true;
if (BuiltinEditorDocumentParser *parser = BuiltinEditorDocumentParser::get(fileName())) {
parser->update(BuiltinEditorDocumentParser::InMemoryInfo(false));
m_snapshot = parser->snapshot();
m_headerPaths = parser->headerPaths();
if (Document::Ptr document = parser->document())
if (m_parser) {
m_parser->update(BuiltinEditorDocumentParser::InMemoryInfo(false));
m_snapshot = m_parser->snapshot();
m_headerPaths = m_parser->headerPaths();
if (Document::Ptr document = m_parser->document())
m_languageFeatures = document->languageFeatures();
else
m_languageFeatures = LanguageFeatures::defaultFeatures();