debugger: gather more information on threads when easily available

This commit is contained in:
hjk
2010-05-17 17:38:31 +02:00
parent 5d5eeed6c0
commit 2f69bae63f
7 changed files with 71 additions and 23 deletions

View File

@@ -129,10 +129,10 @@ bool CdbStackTraceContext::getThreads(const CdbCore::ComInterfaces &cif,
const CdbCore::StackFrame &coreFrame = it.value(); const CdbCore::StackFrame &coreFrame = it.value();
data.address = coreFrame.address; data.address = coreFrame.address;
data.function = coreFrame.function; data.function = coreFrame.function;
data.line = coreFrame.line; data.lineNumber = coreFrame.line;
// Basename only for brevity // Basename only for brevity
const int slashPos = coreFrame.fileName.lastIndexOf(slash); 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); threads->push_back(data);
} }
return true; return true;

View File

@@ -581,7 +581,7 @@ void GdbEngine::updateAllClassic()
QVariant::fromValue<StackCookie>(StackCookie(false, true))); QVariant::fromValue<StackCookie>(StackCookie(false, true)));
manager()->stackHandler()->setCurrentIndex(0); manager()->stackHandler()->setCurrentIndex(0);
if (supportsThreads()) if (supportsThreads())
postCommand("-thread-list-ids", WatchUpdate, CB(handleStackListThreads), 0); postCommand("-thread-list-ids", WatchUpdate, CB(handleThreadListIds), 0);
manager()->reloadRegisters(); manager()->reloadRegisters();
updateLocals(); updateLocals();
} }

View File

@@ -1464,10 +1464,12 @@ void GdbEngine::handleStop1(const GdbMi &data)
if (supportsThreads()) { if (supportsThreads()) {
int currentId = data.findChild("thread-id").data().toInt(); int currentId = data.findChild("thread-id").data().toInt();
if (m_gdbAdapter->isTrkAdapter()) if (m_gdbAdapter->isTrkAdapter()) {
m_gdbAdapter->trkReloadThreads(); m_gdbAdapter->trkReloadThreads();
else } else {
postCommand("-thread-list-ids", CB(handleStackListThreads), currentId); // 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(); 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(); int id = response.cookie.toInt();
// "72^done,{thread-ids={thread-id="2",thread-id="1"},number-of-threads="2"} // "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(); const QList<GdbMi> items = response.data.findChild("thread-ids").children();
QList<ThreadData> threads; QList<ThreadData> threads;
int currentIndex = -1; int currentIndex = -1;

View File

@@ -429,7 +429,8 @@ private: ////////// View & Data Stuff //////////
void handleStackListFrames(const GdbResponse &response); void handleStackListFrames(const GdbResponse &response);
void handleStackSelectThread(const GdbResponse &response); void handleStackSelectThread(const GdbResponse &response);
void handleStackSelectFrame(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 void reloadStack(bool forceGotoLocation);
Q_SLOT virtual void reloadFullStack(); Q_SLOT virtual void reloadFullStack();
int currentFrame() const; int currentFrame() const;

View File

@@ -197,7 +197,7 @@ void GdbEngine::updateAllPython()
if (m_gdbAdapter->isTrkAdapter()) if (m_gdbAdapter->isTrkAdapter())
m_gdbAdapter->trkReloadThreads(); m_gdbAdapter->trkReloadThreads();
else else
postCommand("-thread-list-ids", CB(handleStackListThreads), 0); postCommand("-thread-list-ids", CB(handleThreadListIds), 0);
manager()->reloadRegisters(); manager()->reloadRegisters();
updateLocals(); updateLocals();
} }

View File

@@ -268,19 +268,20 @@ bool StackHandler::isDebuggingDebuggingHelpers() const
// //
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
ThreadData::ThreadData(int threadId) : ThreadData::ThreadData(int threadId)
id(threadId),
address(0),
line(-1)
{ {
notifyRunning();
id = threadId;
} }
void ThreadData::notifyRunning() void ThreadData::notifyRunning()
{ {
address = 0; address = 0;
function.clear(); function.clear();
file.clear(); fileName.clear();
line = -1; frameLevel = -1;
state.clear();
lineNumber = -1;
} }
enum { IdColumn, AddressColumn, FunctionColumn, FileColumn, LineColumn, ColumnCount }; enum { IdColumn, AddressColumn, FunctionColumn, FileColumn, LineColumn, ColumnCount };
@@ -320,9 +321,9 @@ QVariant ThreadsHandler::data(const QModelIndex &index, int role) const
case FunctionColumn: case FunctionColumn:
return thread.function; return thread.function;
case FileColumn: case FileColumn:
return thread.file; return thread.fileName;
case LineColumn: case LineColumn:
return thread.line >= 0 ? QString::number(thread.line) : QString(); return thread.lineNumber >= 0 ? QString::number(thread.lineNumber) : QString();
case AddressColumn: case AddressColumn:
return thread.address > 0 ? QLatin1String("0x") + QString::number(thread.address, 16) : QString(); 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) if (thread.address == 0)
return tr("Thread: %1").arg(thread.id); return tr("Thread: %1").arg(thread.id);
// Stopped // 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 (0x%3)").arg(thread.id).arg(thread.function).arg(thread.address, 0, 16);
return tr("Thread: %1 at %2, %3:%4 (0x%5)"). 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) { } else if (role == Qt::DecorationRole && index.column() == 0) {
// Return icon that indicates whether this is the active stack frame // Return icon that indicates whether this is the active stack frame
return (index.row() == m_currentIndex) ? m_positionIcon : m_emptyIcon; return (index.row() == m_currentIndex) ? m_positionIcon : m_emptyIcon;

View File

@@ -101,14 +101,21 @@ private:
struct ThreadData struct ThreadData
{ {
ThreadData(int threadId = 0); ThreadData(int threadId = 0);
// Permanent data.
int id;
QString targetId;
QString core;
// State information when stopped
void notifyRunning(); // Clear state information void notifyRunning(); // Clear state information
int id; int frameLevel;
// State information when stopped
quint64 address; quint64 address;
QString function; QString function;
QString file; QString fileName;
int line; QString state;
int lineNumber;
}; };
/*! A model to represent the running threads in a QTreeView or ComboBox */ /*! A model to represent the running threads in a QTreeView or ComboBox */