Created attachment 117668 [details] backtrace SUMMARY Commit 7a16881ec33f4af2028593c2b3da7c1e20bf53c6 seems to break the cmake project import fallback to non-server mode. STEPS TO REPRODUCE 1. configure a project that uses an older cmake version (e.g. 3.0.1). This will be detected by the importer which will then fall back to using legacy import mode. 2. close the session 3. restart KDevelop with that session OBSERVED RESULT KDevelop crashes very early in the import process. The crash is deep in Qt, usually under KJob::exec() but not always. QMetaObject::activate() attempts to access an invalid QObject ("sender"). This reeks of a missing initialisation. EXPECTED RESULT No crashing. Reverting the incriminated commit restores that expectation. SOFTWARE/OS VERSIONS Windows: MacOS: 10.9.5 Linux/KDE Plasma: (available in About System) KDE Plasma Version: KDE Frameworks Version: 5.52.0 Qt Version: 5.9.7 ADDITIONAL INFORMATION Starting KDevelop with a session that does not contain CMake projects is still possible, and one can then import CMake-based projects into the running session. Import also completes successfully if one clears the cache directory first. Note : I use the legacy mode for large projects esp. when on a slower machine, via a cmake wrapper that pretends to be an older version that lacks server mode. Legacy mode is some 4-5x faster. This kind of wrapper is easy to write: ``` #!/bin/sh if [ "${1}" = "-E" - a "$2" = "server" -a "`basename $0`" = "cmake_noserver" ] ;then # emulate the error message from an older CMake version ( echo "CMake Error: cmake version 3.0.1 (faked to avoid server mode)" echo "Usage: ${PREFIX}/bin/cmake -E [command] [arguments ...]" ) 1>&2 exit 1 fi exec /usr/bin/cmake "$@" ``` I will check tomorrow if this happens on Linux too.
1). Doesn't happen on Linux 2) I think I have identified the stale QObject instance. It seems to be CMakeServer::m_process . Here's a fresh bit of backtrace: ``` (lldb) bt * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT) frame #0: 0x00000001096d7ad4 QtQml`QQmlData::isSignalConnected(d=0xe4c1490467634d38, (null)=0x078b480774ff8548, index=<unavailable>) at qqmlengine.cpp:869 [opt] frame #1: 0x000000010ba4f6aa QtCore`QMetaObject::activate(QObject*, int, int, void**) [inlined] QObjectPrivate::isDeclarativeSignalConnected(signal_index=<unavailable>) const at qobject_p.h:266 [opt] * frame #2: 0x000000010ba4f68c QtCore`QMetaObject::activate(sender=0x00007f9c465272c0, signalOffset=<unavailable>, local_signal_index=<unavailable>, argv=0x00007fff585b0a90) at qobject.cpp:3647 [opt] frame #3: 0x000000010b9a8772 QtCore`QProcessPrivate::_q_processDied() [inlined] QProcess::finished(_t1=1, _t1=<unavailable>, _t2=NormalExit, _t2=<unavailable>) at moc_qprocess.cpp:334 [opt] frame #4: 0x000000010b9a8746 QtCore`QProcessPrivate::_q_processDied(this=0x00007f9c46527ac0) at qprocess.cpp:1181 [opt] ``` and here is the corresponding terminal output after adding a few trace qWarning calls to cmakemanager.cpp and cmakeserver.cpp: ``` kdevplatform.serialization: version mismatch or no version hint; expected version: 84082945 kdevplatform.serialization: "The data-repository at /Users/bertin/.cache/kdevduchain/kdevelop-{b9a8d6dc-6d10-4bc1-955f-831c48d4ae34} has to be cleared." kdevplatform.shell: Starting project import timer CMakeServer::CMakeServer(KDevelop::IProject *) cmake server process: QProcess(0x7f9c465272c0) virtual void ChooseCMakeInterfaceJob::start() CMakeServer: CMakeServer(0x7f9c465272a0) CMake Error: cmake version 3.0.1 (faked to avoid server mode) Usage: /opt/local/bin/cmake -E [command] [arguments ...] void ChooseCMakeInterfaceJob::failedConnection(int) disconnecting CMakeServer(0x7f9c465272a0) virtual CMakeServer::~CMakeServer() CMakeServer(0x7f9c465272a0) QProcess(0x7f9c465272c0) kdevelop.plugins.cmake: CMake server not available, using compile_commands.json to import "lzvn (MP)" ``` The error here appears to be deleting the QProcess for cmake before that process has had a chance to terminate on its own. Killing a cmake subprocess has always been more likely to crash on Mac than on Linux, IIRC. Here, there are 2 lines in ChooseCMakeInterfaceJob::failedConnection() that have been carried over from the pre-QSharedPointer implementation which lead to deleting the CMakeServer: 1) server->deleteLater(), which is apparently executed immediately here (the cmake server availability warning is printed just after the server instance reset) 2) server = nullptr, which deletes the QSharedPointer's pointer if not shared Deleting both lines resolve the crash, and as mentioned in the 7a16881 commit message, "QSharedPointer will try to delete it [the CMakeServer instance] eventually". If there are no objections I will push the fix soon (say by tomorrow).
A later commit replaces the two lines mentioned above (server->deleteLater() and server = nullptr) with server->clear(). This still causes a crash because `server->clear()` is, AFAICT, equivalent to `server = nullptr`: both expressions delete the shared pointer.
Git commit fba39d4a06a4b2a1fa551383d7dfc0af4fdb82c9 by René J.V. Bertin. Committed on 11/02/2019 at 10:44. Pushed by rjvbb into branch '5.3'. Don't call clear() on a shared pointer we don't own As per the documentation this will delete the pointer itself when the QSharedPointer refcount drops to 0 That can happen while the target QProcess instance is still running, and will happen occasionally (on Mac), causing a crash. The ChooseCMakeInterfaceJob instance will be deleted soon after a failed connection attempt so there is no need to clear the server pointer here. M +1 -1 plugins/cmake/cmakemanager.cpp https://invent.kde.org/kde/kdevelop/commit/fba39d4a06a4b2a1fa551383d7dfc0af4fdb82c9