forked from qt-creator/qt-creator
debugger: gather more information on threads when easily available
This commit is contained in:
@@ -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;
|
||||||
|
@@ -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();
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;
|
||||||
|
@@ -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();
|
||||||
}
|
}
|
||||||
|
@@ -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;
|
||||||
|
@@ -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 */
|
||||||
|
Reference in New Issue
Block a user