From 2f69bae63f4180fc8b34bcefd55d120eca0431ab Mon Sep 17 00:00:00 2001 From: hjk <qtc-committer@nokia.com> Date: Mon, 17 May 2010 17:38:31 +0200 Subject: [PATCH] debugger: gather more information on threads when easily available --- .../debugger/cdb/cdbstacktracecontext.cpp | 4 +- src/plugins/debugger/gdb/classicgdbengine.cpp | 2 +- src/plugins/debugger/gdb/gdbengine.cpp | 47 +++++++++++++++++-- src/plugins/debugger/gdb/gdbengine.h | 3 +- src/plugins/debugger/gdb/pythongdbengine.cpp | 2 +- src/plugins/debugger/stackhandler.cpp | 21 +++++---- src/plugins/debugger/stackhandler.h | 13 +++-- 7 files changed, 70 insertions(+), 22 deletions(-) diff --git a/src/plugins/debugger/cdb/cdbstacktracecontext.cpp b/src/plugins/debugger/cdb/cdbstacktracecontext.cpp index 94ae7df065c..d7e9b7a3981 100644 --- a/src/plugins/debugger/cdb/cdbstacktracecontext.cpp +++ b/src/plugins/debugger/cdb/cdbstacktracecontext.cpp @@ -129,10 +129,10 @@ bool CdbStackTraceContext::getThreads(const CdbCore::ComInterfaces &cif, const CdbCore::StackFrame &coreFrame = it.value(); data.address = coreFrame.address; data.function = coreFrame.function; - data.line = coreFrame.line; + data.lineNumber = coreFrame.line; // Basename only for brevity const int slashPos = coreFrame.fileName.lastIndexOf(slash); - data.file = slashPos == -1 ? coreFrame.fileName : coreFrame.fileName.mid(slashPos + 1); + data.fileName = slashPos == -1 ? coreFrame.fileName : coreFrame.fileName.mid(slashPos + 1); threads->push_back(data); } return true; diff --git a/src/plugins/debugger/gdb/classicgdbengine.cpp b/src/plugins/debugger/gdb/classicgdbengine.cpp index 84066bc534b..3816fc25854 100644 --- a/src/plugins/debugger/gdb/classicgdbengine.cpp +++ b/src/plugins/debugger/gdb/classicgdbengine.cpp @@ -581,7 +581,7 @@ void GdbEngine::updateAllClassic() QVariant::fromValue<StackCookie>(StackCookie(false, true))); manager()->stackHandler()->setCurrentIndex(0); if (supportsThreads()) - postCommand("-thread-list-ids", WatchUpdate, CB(handleStackListThreads), 0); + postCommand("-thread-list-ids", WatchUpdate, CB(handleThreadListIds), 0); manager()->reloadRegisters(); updateLocals(); } diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 78f21a6e0eb..81986228765 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -1464,10 +1464,12 @@ void GdbEngine::handleStop1(const GdbMi &data) if (supportsThreads()) { int currentId = data.findChild("thread-id").data().toInt(); - if (m_gdbAdapter->isTrkAdapter()) + if (m_gdbAdapter->isTrkAdapter()) { m_gdbAdapter->trkReloadThreads(); - else - postCommand("-thread-list-ids", CB(handleStackListThreads), currentId); + } else { + // This is only available in gdb 7.1+. + postCommand("-thread-info", CB(handleThreadInfo), currentId); + } } // @@ -2966,10 +2968,47 @@ void GdbEngine::handleStackSelectFrame(const GdbResponse &response) reloadRegisters(); } -void GdbEngine::handleStackListThreads(const GdbResponse &response) +void GdbEngine::handleThreadInfo(const GdbResponse &response) +{ + int id = response.cookie.toInt(); + if (response.resultClass == GdbResultDone) { + // ^done,threads=[{id="1",target-id="Thread 0xb7fdc710 (LWP 4264)", + // frame={level="0",addr="0x080530bf",func="testQString",args=[], + // file="/.../app.cpp",fullname="/../app.cpp",line="1175"}, + // state="stopped",core="0"}],current-thread-id="1" + const QList<GdbMi> items = response.data.findChild("threads").children(); + QList<ThreadData> threads; + for (int index = 0, n = items.size(); index != n; ++index) { + bool ok = false; + const GdbMi item = items.at(index); + const GdbMi frame = item.findChild("frame"); + ThreadData thread; + thread.id = item.findChild("id").data().toInt(); + thread.targetId = item.findChild("target-id").data().toInt(); + thread.core = QString::fromLatin1(item.findChild("core").data()); + thread.state = QString::fromLatin1(item.findChild("state").data()); + thread.address = frame.findChild("addr").data().toULongLong(&ok, 0); + thread.function = QString::fromLatin1(frame.findChild("func").data()); + thread.fileName = QString::fromLatin1(frame.findChild("fullname").data()); + thread.lineNumber = frame.findChild("line").data().toInt(); + threads.append(thread); + } + ThreadsHandler *threadsHandler = manager()->threadsHandler(); + threadsHandler->setThreads(threads); + int currentIndex = response.data.findChild("current-thread-id").data().toInt(); + threadsHandler->setCurrentThread(currentIndex); + } else { + // Fall back for older versions: Try to get at least a list + // of running threads. + postCommand("-thread-list-ids", CB(handleThreadListIds), id); + } +} + +void GdbEngine::handleThreadListIds(const GdbResponse &response) { int id = response.cookie.toInt(); // "72^done,{thread-ids={thread-id="2",thread-id="1"},number-of-threads="2"} + // In gdb 7.1+ additionally: current-thread-id="1" const QList<GdbMi> items = response.data.findChild("thread-ids").children(); QList<ThreadData> threads; int currentIndex = -1; diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index 372ff4d1318..a1b94ae9ec5 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -429,7 +429,8 @@ private: ////////// View & Data Stuff ////////// void handleStackListFrames(const GdbResponse &response); void handleStackSelectThread(const GdbResponse &response); void handleStackSelectFrame(const GdbResponse &response); - void handleStackListThreads(const GdbResponse &response); + void handleThreadListIds(const GdbResponse &response); + void handleThreadInfo(const GdbResponse &response); Q_SLOT void reloadStack(bool forceGotoLocation); Q_SLOT virtual void reloadFullStack(); int currentFrame() const; diff --git a/src/plugins/debugger/gdb/pythongdbengine.cpp b/src/plugins/debugger/gdb/pythongdbengine.cpp index ebe0dff8f83..db59f7f6b94 100644 --- a/src/plugins/debugger/gdb/pythongdbengine.cpp +++ b/src/plugins/debugger/gdb/pythongdbengine.cpp @@ -197,7 +197,7 @@ void GdbEngine::updateAllPython() if (m_gdbAdapter->isTrkAdapter()) m_gdbAdapter->trkReloadThreads(); else - postCommand("-thread-list-ids", CB(handleStackListThreads), 0); + postCommand("-thread-list-ids", CB(handleThreadListIds), 0); manager()->reloadRegisters(); updateLocals(); } diff --git a/src/plugins/debugger/stackhandler.cpp b/src/plugins/debugger/stackhandler.cpp index 432cef2878e..95c64c68689 100644 --- a/src/plugins/debugger/stackhandler.cpp +++ b/src/plugins/debugger/stackhandler.cpp @@ -268,19 +268,20 @@ bool StackHandler::isDebuggingDebuggingHelpers() const // //////////////////////////////////////////////////////////////////////// -ThreadData::ThreadData(int threadId) : - id(threadId), - address(0), - line(-1) +ThreadData::ThreadData(int threadId) { + notifyRunning(); + id = threadId; } void ThreadData::notifyRunning() { address = 0; function.clear(); - file.clear(); - line = -1; + fileName.clear(); + frameLevel = -1; + state.clear(); + lineNumber = -1; } enum { IdColumn, AddressColumn, FunctionColumn, FileColumn, LineColumn, ColumnCount }; @@ -320,9 +321,9 @@ QVariant ThreadsHandler::data(const QModelIndex &index, int role) const case FunctionColumn: return thread.function; case FileColumn: - return thread.file; + return thread.fileName; case LineColumn: - return thread.line >= 0 ? QString::number(thread.line) : QString(); + return thread.lineNumber >= 0 ? QString::number(thread.lineNumber) : QString(); case AddressColumn: return thread.address > 0 ? QLatin1String("0x") + QString::number(thread.address, 16) : QString(); } @@ -330,10 +331,10 @@ QVariant ThreadsHandler::data(const QModelIndex &index, int role) const if (thread.address == 0) return tr("Thread: %1").arg(thread.id); // Stopped - if (thread.file.isEmpty()) + if (thread.fileName.isEmpty()) return tr("Thread: %1 at %2 (0x%3)").arg(thread.id).arg(thread.function).arg(thread.address, 0, 16); return tr("Thread: %1 at %2, %3:%4 (0x%5)"). - arg(thread.id).arg(thread.function, thread.file).arg(thread.line).arg(thread.address, 0, 16); + arg(thread.id).arg(thread.function, thread.fileName).arg(thread.lineNumber).arg(thread.address, 0, 16); } else if (role == Qt::DecorationRole && index.column() == 0) { // Return icon that indicates whether this is the active stack frame return (index.row() == m_currentIndex) ? m_positionIcon : m_emptyIcon; diff --git a/src/plugins/debugger/stackhandler.h b/src/plugins/debugger/stackhandler.h index 64c0eff0957..f0aa893ad51 100644 --- a/src/plugins/debugger/stackhandler.h +++ b/src/plugins/debugger/stackhandler.h @@ -101,14 +101,21 @@ private: struct ThreadData { ThreadData(int threadId = 0); - void notifyRunning(); // Clear state information + // Permanent data. int id; + QString targetId; + QString core; + // State information when stopped + void notifyRunning(); // Clear state information + + int frameLevel; quint64 address; QString function; - QString file; - int line; + QString fileName; + QString state; + int lineNumber; }; /*! A model to represent the running threads in a QTreeView or ComboBox */ -- GitLab