Uploaded image for project: 'Qt Creator'
  1. Qt Creator
  2. QTCREATORBUG-24112

Qt Creator crash when editing CMakeLists.txt and rerunning CMake

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Reported
    • Priority: P3: Somewhat important
    • Resolution: Unresolved
    • Affects Version/s: Qt Creator 4.12.1
    • Fix Version/s: None
    • Labels:
    • Environment:
      Windows 10 x64
      CMake 3.17.2
    • Platform/s:
      Windows

      Description

      I got a crash in Qt Creator. I have a crash dump, but have not been able to reproduce the crash. I think I was doing the following steps around the time:

      • edit cmakelists and save
      • qt reruns cmake
      • I minimize the window
      • qt creator runs the completion engine? idk.

      This is not a reproducible crash, but an interesting one I decided to spend several days debugging. I debugged the crashed program in Visual Studio, and took a "minidump with heap". Problem is it's huge and contains lots of unrelated stuff.

      Unfortunately the crash dump is 652MB and I can't figure out how to remove the heap. Dump file (compressed via 7z) at https://drive.google.com/file/d/1AOb1km7pDduQTYw1NpZi6kHqZQj8WVOg/view?usp=sharing.

      The backtrace is as follows:

      > Qt5Core.dll!QString::QString(const QString & other) Line 504 C++
      CMakeProjectManager4.dll!QList<QString>::node_copy(QList<QString>::Node * from, QList<QString>::Node * to, QList<QString>::Node * src) Line 506 C++
      CMakeProjectManager4.dll!QList<QString>::operator+=(const QList<QString> & l) Line 988 C++
      [Inline Frame] CMakeProjectManager4.dll!QList<QString>::append(const QList<QString> &) Line 1003 C++
      CMakeProjectManager4.dll!CMakeProjectManager::CMakeTool::keywords() Line 315 C++
      CMakeProjectManager4.dll!CMakeProjectManager::Internal::CMakeFileCompletionAssist::perform(const TextEditor::AssistInterface * interface) Line 70 C++
      TextEditor4.dll!TextEditor::Internal::ProcessorRunner::run() Line 52 C++
      kernel32.dll!@BaseThreadInitThunk@12() Unknown

      Note that this is actually a QStringList, variable IntrospectionData::m_variables.

      Going to the operator+= stack frame (link to code)...

      Loading the minidump in windbg (not windbg preview) and looking at the assembly code (I'm not an assembly expert)...

      64396e83 8bcf mov ecx,edi
      64396e85 c745fc00000000 mov dword ptr [ebp-4],0
      64396e8c ff15a8a14064 call dword ptr [CMakeProjectManager4!_imp_?beginQListDataQBEPAPAXXZ (6440a1a8)]
      64396e92 50 push eax  // pushes l.p.begin() as argument node_copy(src)

      • stack: 078afb38 1d2e5880
      • &l->d->array also has value 0x1d2e5880.

      64396e93 8bce mov ecx,esi
      64396e95 ff15a4a14064 call dword ptr [CMakeProjectManager4!_imp_?endQListDataQBEPAPAXXZ (6440a1a4)]
      64396e9b 50 push eax  // pushes p.end() as argument node_copy(to)

      • stack: 078afb34 17f96040 
      • But d->array + d->end has value 0x17fa5fc8 which does not match the stack!!!

      64396e9c 53 push ebx  // pushes local variable n as argument node_copy(from)

      • stack: 078afb30 22954c44
      • Local variable n also has value 22954c44.

      64396e9d 8bce mov ecx,esi
      64396e9f e8ac12ffff call CMakeProjectManager4!QList<QString>::node_copy (64388150)

      • stack: 078afb2c 64396ea4 CMakeProjectManager4!QList<QString>::operator+=+0xd4 [c:\users\qt\work\build\qt5_install_dir\include\qtcore\qlist.h @ 988]

      Why does n not point into this? Did append() reallocate the memory but forget to update this.p? Or did it update this.p but return a pointer to the old memory? Is there a race condition where two threads are modifying the same QList but failed to increment the refcount? Is there memory corruption?

      • https://code.woboq.org/qt5/qt-creator/src/plugins/cmakeprojectmanager/cmakefilecompletionassist.cpp.html#68
      • CMakeTool *cmake = CMakeKitAspect::cmakeTool(p->activeTarget()->kit());
        • static CMakeTool *cmakeTool(const ProjectExplorer::Kit *k);
        • return CMakeToolManager::findById(cmakeToolId(k));
      • kw = cmake->keywords();
      • There might be a race condition where two threads are accessing this CMakeTool concurrently, one thread is rerunning CMake while the other thread is trying to process text editor completion, but the QList's "copy refcount" is only 1. However I can't find any other threads doing CMake-related work.

      Both this and n seem to point to valid-looking memory, and n points to more of it!

      Debugging in Visual Studio:

      • (QString*)(&*(n-575)),2000 contains valid strings, then this's strings, then a single "", then l's strings, then gibberish.
        • The data before n is quite different from the data found in this. The entries aren't identical, and the ordering is different.
      • (QString*)(&*n),2000 contains l's strings, then gibberish.

      What does this hold?

      • &(*this)[0], 2000 has value 0x17fa4ca0, which equals d->array.
      • Both this and &(*this)[0], 2000 start with a single empty string.

      Where did n and this.d originate from? They seem to be copies of each other.

      • (QString*)(&*(n-2)) is "XCTEST" with d-pointer 0x10e04bb0.
      • (*this)[1225] is also "XCTEST" and shares the same d-pointer (0x10e04bb0)!
      • It has a refcount of 1, not 2.

      Was this->size() modified? Was (*this)[...] modified?

      Summary

      Is there a race condition where two threads mutate one CMakeTool concurrently? Is there a bug in QList's appending functions? (I didn't poke through the assembly yet to find out.) Is there some other memory corruption?

        Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

            Assignee:
            Unassigned
            Reporter:
            anontt Anonymous (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Dates

              Created:
              Updated:

                Gerrit Reviews

                There are no open Gerrit changes