diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 5818ead57b8..702ecdc7e70 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -1352,9 +1352,6 @@ void GdbEngine::handleStopResponse(const GdbMi &data) threadsHandler()->notifyStopped(threads.data()); const QByteArray reason = data["reason"].data(); - const GdbMi frame = data["frame"]; - const QByteArray func = frame["from"].data(); - if (isExitedReason(reason)) { // // The user triggered a stop, but meanwhile the app simply exited ... // QTC_ASSERT(state() == InferiorStopRequested @@ -1370,12 +1367,14 @@ void GdbEngine::handleStopResponse(const GdbMi &data) } else { msg = tr("Application exited normally"); } + // Only show the message. Ramp-down will be triggered by -thread-group-exited. showStatusMessage(msg); - notifyInferiorExited(); return; } // Ignore signals from the process stub. + const GdbMi frame = data["frame"]; + const QByteArray func = frame["from"].data(); if (runParameters().useTerminal && data["reason"].data() == "signal-received" && data["signal-name"].data() == "SIGSTOP" @@ -1963,18 +1962,16 @@ void GdbEngine::handleDetach(const DebuggerResponse &response) void GdbEngine::handleThreadGroupCreated(const GdbMi &result) { - Q_UNUSED(result); -// QByteArray id = result["id"].data(); -// QByteArray pid = result["pid"].data(); -// Q_UNUSED(id); -// Q_UNUSED(pid); + QByteArray groupId = result["id"].data(); + QByteArray pid = result["pid"].data(); + threadsHandler()->notifyGroupCreated(groupId, pid); } void GdbEngine::handleThreadGroupExited(const GdbMi &result) { - Q_UNUSED(result); -// QByteArray id = result["id"].data(); -// Q_UNUSED(id); + QByteArray groupId = result["id"].data(); + if (threadsHandler()->notifyGroupExited(groupId)) + notifyInferiorExited(); } int GdbEngine::currentFrame() const diff --git a/src/plugins/debugger/threadshandler.cpp b/src/plugins/debugger/threadshandler.cpp index d69d9b993dd..ed41f3420ab 100644 --- a/src/plugins/debugger/threadshandler.cpp +++ b/src/plugins/debugger/threadshandler.cpp @@ -314,6 +314,16 @@ void ThreadsHandler::setCurrentThread(ThreadId id) updateThreadBox(); } +QByteArray ThreadsHandler::pidForGroupId(const QByteArray &groupId) const +{ + return m_pidForGroupId[groupId]; +} + +void ThreadsHandler::notifyGroupCreated(const QByteArray &groupId, const QByteArray &pid) +{ + m_pidForGroupId[groupId] = pid; +} + void ThreadsHandler::updateThread(const ThreadData &threadData) { if (ThreadItem *item = itemForThreadId(this, threadData.id)) @@ -360,6 +370,20 @@ void ThreadsHandler::removeAll() rootItem()->removeChildren(); } +bool ThreadsHandler::notifyGroupExited(const QByteArray &groupId) +{ + QList list; + auto items = itemsAtLevel(1); + foreach (ThreadItem *item, items) + if (item->groupId == groupId) + list.append(item); + foreach (ThreadItem *item, list) + delete takeItem(item); + + m_pidForGroupId.remove(groupId); + return m_pidForGroupId.isEmpty(); +} + void ThreadsHandler::notifyRunning(const QByteArray &data) { if (data.isEmpty() || data == "all") { diff --git a/src/plugins/debugger/threadshandler.h b/src/plugins/debugger/threadshandler.h index f335aff9dbf..908a4889f25 100644 --- a/src/plugins/debugger/threadshandler.h +++ b/src/plugins/debugger/threadshandler.h @@ -57,6 +57,7 @@ public: ThreadId currentThread() const; ThreadId threadAt(int index) const; void setCurrentThread(ThreadId id); + QByteArray pidForGroupId(const QByteArray &groupId) const; void updateThread(const ThreadData &threadData); void updateThreads(const GdbMi &data); @@ -67,6 +68,9 @@ public: ThreadData thread(ThreadId id) const; QAbstractItemModel *model(); + void notifyGroupCreated(const QByteArray &groupId, const QByteArray &pid); + bool notifyGroupExited(const QByteArray &groupId); // Returns true when empty. + // Clear out all frame information void notifyRunning(const QByteArray &data); void notifyRunning(ThreadId threadId); @@ -86,6 +90,7 @@ private: ThreadId m_currentId; bool m_resetLocationScheduled; + QHash m_pidForGroupId; }; } // namespace Internal