forked from qt-creator/qt-creator
debugger: work on trk integration
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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()));
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user