debugger: work on trk integration

This commit is contained in:
hjk
2009-09-14 09:46:34 +02:00
parent 4d7abbc1a4
commit 40d54a84dc
3 changed files with 95 additions and 68 deletions

View File

@@ -1265,7 +1265,8 @@ void GdbEngine::reloadFullStack()
void GdbEngine::reloadStack() void GdbEngine::reloadStack()
{ {
QString cmd = _("-stack-list-frames"); QString cmd = _("-stack-list-frames");
if (int stackDepth = theDebuggerAction(MaximalStackDepth)->value().toInt()) int stackDepth = theDebuggerAction(MaximalStackDepth)->value().toInt();
if (stackDepth && !m_gdbAdapter->isAdapter())
cmd += _(" 0 ") + QString::number(stackDepth); cmd += _(" 0 ") + QString::number(stackDepth);
postCommand(cmd, WatchUpdate, CB(handleStackListFrames), false); postCommand(cmd, WatchUpdate, CB(handleStackListFrames), false);
} }
@@ -2493,64 +2494,66 @@ void GdbEngine::handleStackSelectThread(const GdbResultRecord &, const QVariant
void GdbEngine::handleStackListFrames(const GdbResultRecord &record, const QVariant &cookie) void GdbEngine::handleStackListFrames(const GdbResultRecord &record, const QVariant &cookie)
{ {
bool isFull = cookie.toBool(); if (record.resultClass == GdbResultDone) {
QList<StackFrame> stackFrames; bool isFull = cookie.toBool();
QList<StackFrame> stackFrames;
const GdbMi stack = record.data.findChild("stack"); GdbMi stack = record.data.findChild("stack");
stack.toString(); if (!stack.isValid()) {
if (!stack.isValid()) { qDebug() << "FIXME: stack:" << stack.toString();
qDebug() << "FIXME: stack:" << stack.toString();
return;
}
int topFrame = -1;
int n = stack.childCount();
for (int i = 0; i != n; ++i) {
//qDebug() << "HANDLING FRAME:" << stack.childAt(i).toString();
const GdbMi frameMi = stack.childAt(i);
StackFrame frame(i);
QStringList files;
files.append(QFile::decodeName(frameMi.findChild("fullname").data()));
files.append(QFile::decodeName(frameMi.findChild("file").data()));
frame.file = fullName(files);
frame.function = _(frameMi.findChild("func").data());
frame.from = _(frameMi.findChild("from").data());
frame.line = frameMi.findChild("line").data().toInt();
frame.address = _(frameMi.findChild("addr").data());
stackFrames.append(frame);
#if defined(Q_OS_WIN)
const bool isBogus =
// Assume this is wrong and points to some strange stl_algobase
// implementation. Happens on Karsten's XP system with Gdb 5.50
(frame.file.endsWith(__("/bits/stl_algobase.h")) && frame.line == 150)
// Also wrong. Happens on Vista with Gdb 5.50
|| (frame.function == __("operator new") && frame.line == 151);
// immediately leave bogus frames
if (topFrame == -1 && isBogus) {
postCommand(_("-exec-finish"));
return; return;
} }
#endif int topFrame = -1;
// Initialize top frame to the first valid frame int n = stack.childCount();
const bool isValid = !frame.file.isEmpty() && !frame.function.isEmpty(); for (int i = 0; i != n; ++i) {
if (isValid && topFrame == -1) //qDebug() << "HANDLING FRAME:" << stack.childAt(i).toString();
topFrame = i; const GdbMi frameMi = stack.childAt(i);
} StackFrame frame(i);
QStringList files;
files.append(QFile::decodeName(frameMi.findChild("fullname").data()));
files.append(QFile::decodeName(frameMi.findChild("file").data()));
frame.file = fullName(files);
frame.function = _(frameMi.findChild("func").data());
frame.from = _(frameMi.findChild("from").data());
frame.line = frameMi.findChild("line").data().toInt();
frame.address = _(frameMi.findChild("addr").data());
bool canExpand = !isFull stackFrames.append(frame);
&& (n >= theDebuggerAction(MaximalStackDepth)->value().toInt());
theDebuggerAction(ExpandStack)->setEnabled(canExpand);
qq->stackHandler()->setFrames(stackFrames, canExpand);
if (topFrame != -1 || theDebuggerBoolSetting(StepByInstruction)) { #if defined(Q_OS_WIN)
const StackFrame &frame = qq->stackHandler()->currentFrame(); const bool isBogus =
q->gotoLocation(frame, true); // Assume this is wrong and points to some strange stl_algobase
// implementation. Happens on Karsten's XP system with Gdb 5.50
(frame.file.endsWith(__("/bits/stl_algobase.h")) && frame.line == 150)
// Also wrong. Happens on Vista with Gdb 5.50
|| (frame.function == __("operator new") && frame.line == 151);
// immediately leave bogus frames
if (topFrame == -1 && isBogus) {
postCommand(_("-exec-finish"));
return;
}
#endif
// Initialize top frame to the first valid frame
const bool isValid = !frame.file.isEmpty() && !frame.function.isEmpty();
if (isValid && topFrame == -1)
topFrame = i;
}
bool canExpand = !isFull
&& (n >= theDebuggerAction(MaximalStackDepth)->value().toInt());
theDebuggerAction(ExpandStack)->setEnabled(canExpand);
qq->stackHandler()->setFrames(stackFrames, canExpand);
if (topFrame != -1 || theDebuggerBoolSetting(StepByInstruction)) {
const StackFrame &frame = qq->stackHandler()->currentFrame();
q->gotoLocation(frame, true);
}
} else if (record.resultClass == GdbResultError) {
qDebug() << "STACK FAILED: " << record.toString();
} }
} }
@@ -3619,8 +3622,8 @@ void GdbEngine::updateLocals()
{ {
// Asynchronous load of injected library, initialize in first stop // Asynchronous load of injected library, initialize in first stop
if (m_dumperInjectionLoad && m_debuggingHelperState == DebuggingHelperLoadTried if (m_dumperInjectionLoad && m_debuggingHelperState == DebuggingHelperLoadTried
&& m_dumperHelper.typeCount() == 0 && m_dumperHelper.typeCount() == 0
&& q->inferiorPid() > 0) && q->inferiorPid() > 0)
tryQueryDebuggingHelpers(); tryQueryDebuggingHelpers();
m_pendingRequests = 0; m_pendingRequests = 0;

View File

@@ -71,15 +71,13 @@ static QByteArray dumpRegister(int n, uint value)
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal {
trk::Endianness m_registerEndianness = LittleEndian;
TrkGdbAdapter::TrkGdbAdapter() TrkGdbAdapter::TrkGdbAdapter()
{ {
m_running = false; m_running = false;
m_gdbAckMode = true; m_gdbAckMode = true;
m_verbose = 2; m_verbose = 2;
m_serialFrame = false; m_serialFrame = false;
m_bufferedMemoryRead = false; m_bufferedMemoryRead = true;
m_rfcommDevice = "/dev/rfcomm0"; m_rfcommDevice = "/dev/rfcomm0";
uid_t userId = getuid(); uid_t userId = getuid();
@@ -530,18 +528,18 @@ void TrkGdbAdapter::handleGdbServerCommand(const QByteArray &cmd)
QByteArray logMsg = "Read Register"; QByteArray logMsg = "Read Register";
if (registerNumber == RegisterPSGdb) { if (registerNumber == RegisterPSGdb) {
QByteArray ba; QByteArray ba;
appendInt(&ba, m_snapshot.registers[RegisterPSTrk], m_registerEndianness); appendInt(&ba, m_snapshot.registers[RegisterPSTrk], LittleEndian);
logMsg += dumpRegister(registerNumber, m_snapshot.registers[RegisterPSTrk]); logMsg += dumpRegister(registerNumber, m_snapshot.registers[RegisterPSTrk]);
sendGdbServerMessage(ba.toHex(), logMsg); sendGdbServerMessage(ba.toHex(), logMsg);
} else if (registerNumber < RegisterCount) { } else if (registerNumber < 16) {
QByteArray ba; QByteArray ba;
appendInt(&ba, m_snapshot.registers[registerNumber], m_registerEndianness); appendInt(&ba, m_snapshot.registers[registerNumber], LittleEndian);
logMsg += dumpRegister(registerNumber, m_snapshot.registers[registerNumber]); logMsg += dumpRegister(registerNumber, m_snapshot.registers[registerNumber]);
sendGdbServerMessage(ba.toHex(), logMsg); sendGdbServerMessage(ba.toHex(), logMsg);
} else { } else {
sendGdbServerMessage("0000", "read single unknown register #" //sendGdbServerMessage("0000", "read single unknown register #"
+ QByteArray::number(registerNumber)); // + QByteArray::number(registerNumber));
//sendGdbServerMessage("E01", "read single unknown register"); sendGdbServerMessage("E01", "read single unknown register");
} }
} }
@@ -801,7 +799,12 @@ void TrkGdbAdapter::handleTrkResult(const TrkResult &result)
// query is pending, queue instead // query is pending, queue instead
if (m_running) { if (m_running) {
m_running = false; m_running = false;
sendGdbServerMessage("S05", "Target stopped"); // We almost always need register values, so get them
// now before informing gdb about the stop. In theory
//sendGdbServerMessage("S05", "Target stopped");
sendTrkMessage(0x12,
TrkCB(handleAndReportReadRegistersAfterStop),
trkReadRegisterMessage());
} }
} else { } else {
logMessage(QLatin1String("Ignoring stop at 0")); logMessage(QLatin1String("Ignoring stop at 0"));
@@ -952,8 +955,7 @@ void TrkGdbAdapter::handleAndReportReadRegisters(const TrkResult &result)
handleReadRegisters(result); handleReadRegisters(result);
QByteArray ba; QByteArray ba;
for (int i = 0; i < 16; ++i) { for (int i = 0; i < 16; ++i) {
const uint reg = m_registerEndianness == LittleEndian const uint reg = swapEndian(m_snapshot.registers[i]);
? swapEndian(m_snapshot.registers[i]) : m_snapshot.registers[i];
ba += hexNumber(reg, 8); ba += hexNumber(reg, 8);
} }
QByteArray logMsg = "REGISTER CONTENTS: "; QByteArray logMsg = "REGISTER CONTENTS: ";
@@ -966,6 +968,27 @@ void TrkGdbAdapter::handleAndReportReadRegisters(const TrkResult &result)
sendGdbServerMessage(ba, logMsg); sendGdbServerMessage(ba, logMsg);
} }
static void appendRegister(QByteArray *ba, uint regno, uint value)
{
ba->append(hexNumber(regno, 2));
ba->append(':');
ba->append(hexNumber(swapEndian(value), 8));
ba->append(';');
}
void TrkGdbAdapter::handleAndReportReadRegistersAfterStop(const TrkResult &result)
{
handleReadRegisters(result);
QByteArray ba = "T05";
for (int i = 0; i < 16; ++i)
appendRegister(&ba, i, m_snapshot.registers[i]);
//for (int i = 16; i < 25; ++i)
// appendRegister(&ba, i, 0x0);
appendRegister(&ba, RegisterPSGdb, m_snapshot.registers[RegisterPSTrk]);
qDebug() << "TrkGdbAdapter::handleAndReportReadRegistersAfterStop" << ba;
sendGdbServerMessage(ba, "Registers");
}
static QString msgMemoryReadError(int code, uint addr, uint len = 0) static QString msgMemoryReadError(int code, uint addr, uint len = 0)
{ {
const QString lenS = len ? QString::number(len) : QLatin1String("<unknown>"); const QString lenS = len ? QString::number(len) : QLatin1String("<unknown>");
@@ -1271,8 +1294,8 @@ void TrkGdbAdapter::startGdb()
return; return;
} }
logMessage(QString("Gdb server running on %1.\nRegister endianness: %3.") logMessage(QString("Gdb server running on %1.\nLittle endian assumed.")
.arg(m_gdbServerName).arg(m_registerEndianness)); .arg(m_gdbServerName));
connect(&m_gdbServer, SIGNAL(newConnection()), connect(&m_gdbServer, SIGNAL(newConnection()),
this, SLOT(handleGdbConnection())); this, SLOT(handleGdbConnection()));

View File

@@ -158,6 +158,7 @@ public:
void handleAndReportCreateProcess(const TrkResult &result); void handleAndReportCreateProcess(const TrkResult &result);
void handleAndReportReadRegisters(const TrkResult &result); void handleAndReportReadRegisters(const TrkResult &result);
void handleAndReportReadRegistersAfterStop(const TrkResult &result);
QByteArray memoryReadLogMessage(uint addr, uint len, const QByteArray &ba) const; QByteArray memoryReadLogMessage(uint addr, uint len, const QByteArray &ba) const;
QByteArray trkContinueMessage(); QByteArray trkContinueMessage();
QByteArray trkReadRegisterMessage(); QByteArray trkReadRegisterMessage();