STEPS TO REPRODUCE 1. Add a breakpoint to a function that contains a local variable and is invoked twice while a debuggee is executed. 2. Start debugging with GDB and wait till the breakpoint is hit. 3. Type the name of the local variable in the Variables tool view and press Enter to watch it. 4. Expand the tree item Auto in the Variables tool view. 5. Continue and finish the GDB debug session. 6. Select LLDB in the Debugger combobox on the Debug subpage of the current launch configuration (Run => Configure Launches...). 7. Start debugging the same debuggee with LLDB and wait till the same breakpoint is hit. 8. Continue and wait till the same breakpoint is hit again. OBSERVED RESULT KDevelop segfaults with the following backtrace: #0 0x00007f87b0ac2e84 in KDevelop::Variable::topLevel (this=0x0) at kdevelop/kdevplatform/debugger/variable/variablecollection.h:92 #1 0x00007f87b0ac13ae in KDevMI::LLDB::DebugSession::updateAllVariables (this=0x5555e2677200) at kdevelop/plugins/lldb/debugsession.cpp:462 #2 0x00007f87b0acece0 in KDevMI::LLDB::VariableController::update (this=0x7f87c4004330) at kdevelop/plugins/lldb/controllers/variablecontroller.cpp:48 #3 0x00007f87f6397e3d in KDevelop::IVariableController::updateIfFrameOrThreadChanged (this=0x7f87c4004330) at kdevelop/kdevplatform/debugger/interfaces/ivariablecontroller.cpp:84 #4 0x00007f87f639805d in KDevelop::IVariableController::handleEvent (this=0x7f87c4004330, event=KDevelop::IDebugSession::thread_or_frame_changed) at kdevelop/kdevplatform/debugger/interfaces/ivariablecontroller.cpp:106 #5 0x00007f87b0b23c0e in KDevMI::MIVariableController::handleEvent (this=0x7f87c4004330, event=KDevelop::IDebugSession::thread_or_frame_changed) at kdevelop/plugins/debuggercommon/mivariablecontroller.cpp:239 #6 0x00007f87f638c9bb in KDevelop::IDebugSession::raiseEvent (this=0x5555e2677200, e=KDevelop::IDebugSession::thread_or_frame_changed) at kdevelop/kdevplatform/debugger/interfaces/idebugsession.cpp:76 #7 0x00007f87b0af4704 in KDevMI::MIDebugSession::raiseEvent (this=0x5555e2677200, e=KDevelop::IDebugSession::thread_or_frame_changed) at kdevelop/plugins/debuggercommon/midebugsession.cpp:925 #8 0x00007f87f63dc63c in KDevelop::FrameStackModel::setCurrentFrame (this=0x5555e4156770, frame=-1) at kdevelop/kdevplatform/debugger/framestack/framestackmodel.cpp:391 #9 0x00007f87f63dc768 in KDevelop::FrameStackModel::stateChanged (this=0x5555e4156770, state=KDevelop::IDebugSession::PausedState) at kdevelop/kdevplatform/debugger/framestack/framestackmodel.cpp:425 #10 0x00007f87f63e29ce in QtPrivate::FunctorCall<std::integer_sequence<unsigned long, 0ul>, QtPrivate::List<KDevelop::IDebugSession::DebuggerState>, void, void (KDevelop::FrameStackModel::*)(KDevelop::IDebugSession::DebuggerState)>::call(void (KDevelop::FrameStackModel::*)(KDevelop::IDebugSession::DebuggerState), KDevelop::FrameStackModel*, void**)::{lambda()#1}::operator()() const (__closure=0x7fff20f28310) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:127 #11 0x00007f87f63e39c7 in QtPrivate::FunctorCallBase::call_internal<void, QtPrivate::FunctorCall<std::integer_sequence<unsigned long, 0ul>, QtPrivate::List<KDevelop::IDebugSession::DebuggerState>, void, void (KDevelop::FrameStackModel::*)(KDevelop::IDebugSession::DebuggerState)>::call(void (KDevelop::FrameStackModel::*)(KDevelop::IDebugSession::DebuggerState), KDevelop::FrameStackModel*, void**)::{lambda()#1}>(void**, QtPrivate::FunctorCall<std::integer_sequence<unsigned long, 0ul>, QtPrivate::List<KDevelop::IDebugSession::DebuggerState>, void, void (KDevelop::FrameStackModel::*)(KDevelop::IDebugSession::DebuggerState)>::call(void (KDevelop::FrameStackModel::*)(KDevelop::IDebugSession::DebuggerState), KDevelop::FrameStackModel*, void**)::{lambda()#1}&&) (args=0x7fff20f284e0, fn=...) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:65 #12 0x00007f87f63e2a40 in QtPrivate::FunctorCall<std::integer_sequence<unsigned long, 0ul>, QtPrivate::List<KDevelop::IDebugSession::DebuggerState>, void, void (KDevelop::FrameStackModel::*)(KDevelop::IDebugSession::DebuggerState)>::call (f=(void (KDevelop::FrameStackModel::*)(KDevelop::FrameStackModel * const, KDevelop::IDebugSession::DebuggerState)) 0x7f87f63dc716 <KDevelop::FrameStackModel::stateChanged(KDevelop::IDebugSession::DebuggerState)>, o=0x5555e4156770, arg=0x7fff20f284e0) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:126 #13 0x00007f87f63e110e in QtPrivate::FunctionPointer<void (KDevelop::FrameStackModel::*)(KDevelop::IDebugSession::DebuggerState)>::call<QtPrivate::List<KDevelop::IDebugSession::DebuggerState>, void> (f=(void (KDevelop::FrameStackModel::*)(KDevelop::FrameStackModel * const, KDevelop::IDebugSession::DebuggerState)) 0x7f87f63dc716 <KDevelop::FrameStackModel::stateChanged(KDevelop::IDebugSession::DebuggerState)>, o=0x5555e4156770, arg=0x7fff20f284e0) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:174 #14 0x00007f87f63dfd71 in QtPrivate::QCallableObject<void (KDevelop::FrameStackModel::*)(KDevelop::IDebugSession::DebuggerState), QtPrivate::List<KDevelop::IDebugSession::DebuggerState>, void>::impl (which=1, this_=0x5555e3318260, r=0x5555e4156770, a=0x7fff20f284e0, ret=0x0) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:545 #15 0x00007f87f5dd37ef in ??? () at /usr/lib/libQt6Core.so.6 #16 0x00007f87f638f4ff in QMetaObject::activate<void, KDevelop::IDebugSession::DebuggerState> (sender=0x5555e2677200, mo=0x7f87f641c9e0 <KDevelop::IDebugSession::staticMetaObject>, local_signal_index=0, ret=0x0) at /usr/include/qt6/QtCore/qobjectdefs.h:306 #17 0x00007f87f638d63a in KDevelop::IDebugSession::stateChanged (this=0x5555e2677200, _t1=KDevelop::IDebugSession::PausedState) at kdevelop/build/kdevplatform/debugger/KDevPlatformDebugger_autogen/include/moc_idebugsession.cpp:227 #18 0x00007f87b0af0677 in KDevMI::MIDebugSession::setSessionState (this=0x5555e2677200, state=KDevelop::IDebugSession::PausedState) at kdevelop/plugins/debuggercommon/midebugsession.cpp:386 #19 0x00007f87b0af0e28 in KDevMI::MIDebugSession::handleDebuggerStateChange (this=0x5555e2677200, oldState=..., newState=...) at kdevelop/plugins/debuggercommon/midebugsession.cpp:471 #20 0x00007f87b0af083c in KDevMI::MIDebugSession::setDebuggerStateOff (this=0x5555e2677200, stateOff=...) at kdevelop/plugins/debuggercommon/midebugsession.cpp:411 #21 0x00007f87b0af4d21 in KDevMI::MIDebugSession::slotInferiorStopped (this=0x5555e2677200, r=...) at kdevelop/plugins/debuggercommon/midebugsession.cpp:1010 #22 0x00007f87b0afebf9 in QtPrivate::FunctorCall<std::integer_sequence<unsigned long, 0ul>, QtPrivate::List<KDevMI::MI::AsyncRecord const&>, void, void (KDevMI::MIDebugSession::*)(KDevMI::MI::AsyncRecord const&)>::call(void (KDevMI::MIDebugSession::*)(KDevMI::MI::AsyncRecord const&), KDevMI::MIDebugSession*, void**)::{lambda()#1}::operator()() const (__closure=0x7fff20f288e0) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:127 #23 0x00007f87b0aff462 in QtPrivate::FunctorCallBase::call_internal<void, QtPrivate::FunctorCall<std::integer_sequence<unsigned long, 0ul>, QtPrivate::List<KDevMI::MI::AsyncRecord const&>, void, void (KDevMI::MIDebugSession::*)(KDevMI::MI::AsyncRecord const&)>::call(void (KDevMI::MIDebugSession::*)(KDevMI::MI::AsyncRecord const&), KDevMI::MIDebugSession*, void**)::{lambda()#1}>(void**, QtPrivate::FunctorCall<std::integer_sequence<unsigned long, 0ul>, QtPrivate::List<KDevMI::MI::AsyncRecord const&>, void, void (KDevMI::MIDebugSession::*)(KDevMI::MI::AsyncRecord const&)>::call(void (KDevMI::MIDebugSession::*)(KDevMI::MI::AsyncRecord const&), KDevMI::MIDebugSession*, void**)::{lambda()#1}&&) (args=0x7fff20f28ab0, fn=...) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:65 #24 0x00007f87b0afec6b in QtPrivate::FunctorCall<std::integer_sequence<unsigned long, 0ul>, QtPrivate::List<KDevMI::MI::AsyncRecord const&>, void, void (KDevMI::MIDebugSession::*)(KDevMI::MI::AsyncRecord const&)>::call (f=&virtual KDevMI::MIDebugSession::slotInferiorStopped(KDevMI::MI::AsyncRecord const&), o=0x5555e2677200, arg=0x7fff20f28ab0) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:126 #25 0x00007f87b0afe20e in QtPrivate::FunctionPointer<void (KDevMI::MIDebugSession::*)(KDevMI::MI::AsyncRecord const&)>::call<QtPrivate::List<KDevMI::MI::AsyncRecord const&>, void> (f=&virtual KDevMI::MIDebugSession::slotInferiorStopped(KDevMI::MI::AsyncRecord const&), o=0x5555e2677200, arg=0x7fff20f28ab0) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:174 #26 0x00007f87b0afd70f in QtPrivate::QCallableObject<void (KDevMI::MIDebugSession::*)(KDevMI::MI::AsyncRecord const&), QtPrivate::List<KDevMI::MI::AsyncRecord const&>, void>::impl (which=1, this_=0x5555e35a3080, r=0x5555e2677200, a=0x7fff20f28ab0, ret=0x0) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:545 #27 0x00007f87f5dd37ef in ??? () at /usr/lib/libQt6Core.so.6 #28 0x00007f87b0aeb8e6 in QMetaObject::activate<void, KDevMI::MI::AsyncRecord> (sender=0x5555e3e286c0, mo=0x7f87b0ba6b80 <KDevMI::MIDebugger::staticMetaObject>, local_signal_index=2, ret=0x0) at /usr/include/qt6/QtCore/qobjectdefs.h:306 #29 0x00007f87b0ae9b24 in KDevMI::MIDebugger::programStopped (this=0x5555e3e286c0, _t1=...) at kdevelop/build/plugins/debuggercommon/kdevdebuggercommon_autogen/include/moc_midebugger.cpp:238 #30 0x00007f87b0ae81e8 in KDevMI::MIDebugger::processLine (this=0x5555e3e286c0, line="*stopped,reason=\"breakpoint-hit\",disp=\"del\",bkptno=\"8\",frame={level=\"0\",addr=\"0x0000555555555170\",func=\"foo()\",args=[],file=\"debugee.cpp\",fullname=\"kdevelop/plugins/debuggercomm"... = {...}) at kdevelop/plugins/debuggercommon/midebugger.cpp:254 #31 0x00007f87b0ae703d in KDevMI::MIDebugger::readyReadStandardOutput (this=0x5555e3e286c0) at kdevelop/plugins/debuggercommon/midebugger.cpp:139 #32 0x00007f87b0aece8a in QtPrivate::FunctorCall<std::integer_sequence<unsigned long>, QtPrivate::List<>, void, void (KDevMI::MIDebugger::*)()>::call(void (KDevMI::MIDebugger::*)(), KDevMI::MIDebugger*, void**)::{lambda()#1}::operator()() const (__closure=0x7fff20f28f10) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:127 #33 0x00007f87b0aed233 in QtPrivate::FunctorCallBase::call_internal<void, QtPrivate::FunctorCall<std::integer_sequence<unsigned long>, QtPrivate::List<>, void, void (KDevMI::MIDebugger::*)()>::call(void (KDevMI::MIDebugger::*)(), KDevMI::MIDebugger*, void**)::{lambda()#1}>(void**, QtPrivate::FunctorCall<std::integer_sequence<unsigned long>, QtPrivate::List<>, void, void (KDevMI::MIDebugger::*)()>::call(void (KDevMI::MIDebugger::*)(), KDevMI::MIDebugger*, void**)::{lambda()#1}&&) (args=0x7fff20f290f0, fn=...) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:65 #34 0x00007f87b0aecefc in QtPrivate::FunctorCall<std::integer_sequence<unsigned long>, QtPrivate::List<>, void, void (KDevMI::MIDebugger::*)()>::call(void (KDevMI::MIDebugger::*)(), KDevMI::MIDebugger*, void**) (f=(void (KDevMI::MIDebugger::*)(KDevMI::MIDebugger * const)) 0x7f87b0ae6da8 <KDevMI::MIDebugger::readyReadStandardOutput()>, o=0x5555e3e286c0, arg=0x7fff20f290f0) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:126 #35 0x00007f87b0aecc9c in QtPrivate::FunctionPointer<void (KDevMI::MIDebugger::*)()>::call<QtPrivate::List<>, void>(void (KDevMI::MIDebugger::*)(), KDevMI::MIDebugger*, void**) (f=(void (KDevMI::MIDebugger::*)(KDevMI::MIDebugger * const)) 0x7f87b0ae6da8 <KDevMI::MIDebugger::readyReadStandardOutput()>, o=0x5555e3e286c0, arg=0x7fff20f290f0) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:174 #36 0x00007f87b0aec727 in QtPrivate::QCallableObject<void (KDevMI::MIDebugger::*)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (which=1, this_=0x5555e29645e0, r=0x5555e3e286c0, a=0x7fff20f290f0, ret=0x0) at /usr/include/qt6/QtCore/qobjectdefs_impl.h:545 #37 0x00007f87f5dd37ef in ??? () at /usr/lib/libQt6Core.so.6 #38 0x00007f87f5f8f5d5 in ??? () at /usr/lib/libQt6Core.so.6 #39 0x00007f87f5f967d4 in ??? () at /usr/lib/libQt6Core.so.6 #40 0x00007f87f5dd3b8a in ??? () at /usr/lib/libQt6Core.so.6 #41 0x00007f87f5dddb40 in QSocketNotifier::event(QEvent*) () at /usr/lib/libQt6Core.so.6 #42 0x00007f87f7901c70 in QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /usr/lib/libQt6Widgets.so.6 #43 0x00007f87f5d68118 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () at /usr/lib/libQt6Core.so.6 #44 0x00007f87f603f9f2 in ??? () at /usr/lib/libQt6Core.so.6 #45 0x00007f87e8308880 in ??? () at /usr/lib/libglib-2.0.so.0 #46 0x00007f87e8309cd7 in ??? () at /usr/lib/libglib-2.0.so.0 #47 0x00007f87e8309ee5 in g_main_context_iteration () at /usr/lib/libglib-2.0.so.0 #48 0x00007f87f603c5e2 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/lib/libQt6Core.so.6 #49 0x00007f87f5d744b6 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () at /usr/lib/libQt6Core.so.6 #50 0x00007f87f5d6c7c1 in QCoreApplication::exec() () at /usr/lib/libQt6Core.so.6 #51 0x00005555a8e0fedc in main (argc=3, argv=0x7fff20f2a108) at kdevelop/app/main.cpp:836 In LLDB::DebugSession::updateAllVariables(): `variable` is non-null, but `var` is null. Clearly qobject_cast<LldbVariable*> has failed because the variable is not an LLDB variable.
If we clear all watches (rather than adapt or recreate them) when a debug session of a different type starts, we should probably also pre-expand the then-empty "Auto" section of the Variables tool view, as is done in VariableTree() when the tool view is created. See also https://invent.kde.org/kdevelop/kdevelop/-/merge_requests/848#note_1355027