Debugger: Don't quit on inferior-exited.

We might have "follow-fork-mode child" and it's only the parent exiting.
Instead quit when the last known thread is gone.

Change-Id: I77a017e6f57ae0ee383aabd2b6f0377ff8261d41
Reviewed-by: Christian Stenger <christian.stenger@theqtcompany.com>
Reviewed-by: Christian Kandeler <christian.kandeler@theqtcompany.com>
This commit is contained in:
hjk
2015-06-12 15:17:14 +02:00
parent f15d177ffd
commit 42be4ef64f
3 changed files with 38 additions and 12 deletions

View File

@@ -1352,9 +1352,6 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
threadsHandler()->notifyStopped(threads.data()); threadsHandler()->notifyStopped(threads.data());
const QByteArray reason = data["reason"].data(); const QByteArray reason = data["reason"].data();
const GdbMi frame = data["frame"];
const QByteArray func = frame["from"].data();
if (isExitedReason(reason)) { if (isExitedReason(reason)) {
// // The user triggered a stop, but meanwhile the app simply exited ... // // The user triggered a stop, but meanwhile the app simply exited ...
// QTC_ASSERT(state() == InferiorStopRequested // QTC_ASSERT(state() == InferiorStopRequested
@@ -1370,12 +1367,14 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
} else { } else {
msg = tr("Application exited normally"); msg = tr("Application exited normally");
} }
// Only show the message. Ramp-down will be triggered by -thread-group-exited.
showStatusMessage(msg); showStatusMessage(msg);
notifyInferiorExited();
return; return;
} }
// Ignore signals from the process stub. // Ignore signals from the process stub.
const GdbMi frame = data["frame"];
const QByteArray func = frame["from"].data();
if (runParameters().useTerminal if (runParameters().useTerminal
&& data["reason"].data() == "signal-received" && data["reason"].data() == "signal-received"
&& data["signal-name"].data() == "SIGSTOP" && data["signal-name"].data() == "SIGSTOP"
@@ -1963,18 +1962,16 @@ void GdbEngine::handleDetach(const DebuggerResponse &response)
void GdbEngine::handleThreadGroupCreated(const GdbMi &result) void GdbEngine::handleThreadGroupCreated(const GdbMi &result)
{ {
Q_UNUSED(result); QByteArray groupId = result["id"].data();
// QByteArray id = result["id"].data(); QByteArray pid = result["pid"].data();
// QByteArray pid = result["pid"].data(); threadsHandler()->notifyGroupCreated(groupId, pid);
// Q_UNUSED(id);
// Q_UNUSED(pid);
} }
void GdbEngine::handleThreadGroupExited(const GdbMi &result) void GdbEngine::handleThreadGroupExited(const GdbMi &result)
{ {
Q_UNUSED(result); QByteArray groupId = result["id"].data();
// QByteArray id = result["id"].data(); if (threadsHandler()->notifyGroupExited(groupId))
// Q_UNUSED(id); notifyInferiorExited();
} }
int GdbEngine::currentFrame() const int GdbEngine::currentFrame() const

View File

@@ -314,6 +314,16 @@ void ThreadsHandler::setCurrentThread(ThreadId id)
updateThreadBox(); 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) void ThreadsHandler::updateThread(const ThreadData &threadData)
{ {
if (ThreadItem *item = itemForThreadId(this, threadData.id)) if (ThreadItem *item = itemForThreadId(this, threadData.id))
@@ -360,6 +370,20 @@ void ThreadsHandler::removeAll()
rootItem()->removeChildren(); rootItem()->removeChildren();
} }
bool ThreadsHandler::notifyGroupExited(const QByteArray &groupId)
{
QList<ThreadItem *> list;
auto items = itemsAtLevel<ThreadItem *>(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) void ThreadsHandler::notifyRunning(const QByteArray &data)
{ {
if (data.isEmpty() || data == "all") { if (data.isEmpty() || data == "all") {

View File

@@ -57,6 +57,7 @@ public:
ThreadId currentThread() const; ThreadId currentThread() const;
ThreadId threadAt(int index) const; ThreadId threadAt(int index) const;
void setCurrentThread(ThreadId id); void setCurrentThread(ThreadId id);
QByteArray pidForGroupId(const QByteArray &groupId) const;
void updateThread(const ThreadData &threadData); void updateThread(const ThreadData &threadData);
void updateThreads(const GdbMi &data); void updateThreads(const GdbMi &data);
@@ -67,6 +68,9 @@ public:
ThreadData thread(ThreadId id) const; ThreadData thread(ThreadId id) const;
QAbstractItemModel *model(); QAbstractItemModel *model();
void notifyGroupCreated(const QByteArray &groupId, const QByteArray &pid);
bool notifyGroupExited(const QByteArray &groupId); // Returns true when empty.
// Clear out all frame information // Clear out all frame information
void notifyRunning(const QByteArray &data); void notifyRunning(const QByteArray &data);
void notifyRunning(ThreadId threadId); void notifyRunning(ThreadId threadId);
@@ -86,6 +90,7 @@ private:
ThreadId m_currentId; ThreadId m_currentId;
bool m_resetLocationScheduled; bool m_resetLocationScheduled;
QHash<QByteArray, QByteArray> m_pidForGroupId;
}; };
} // namespace Internal } // namespace Internal