debugger: make gdb-6.8-symbianelf work

This commit is contained in:
hjk
2009-12-18 16:25:59 +01:00
parent 3023495c71
commit 9ad447b8a4
5 changed files with 137 additions and 45 deletions

View File

@@ -26,8 +26,12 @@ def qmin(n, m):
return n return n
return m return m
def isGoodGdb():
return gdb.VERSION.startswith("6.8.50.2009") \
and gdb.VERSION != "6.8.50.20090630-cvs"
def parseAndEvaluate(exp): def parseAndEvaluate(exp):
if gdb.VERSION.startswith("6.8.50.2009"): if isGoodGdb():
return gdb.parse_and_eval(exp) return gdb.parse_and_eval(exp)
# Work around non-existing gdb.parse_and_eval as in released 7.0 # Work around non-existing gdb.parse_and_eval as in released 7.0
gdb.execute("set logging redirect on") gdb.execute("set logging redirect on")
@@ -41,10 +45,10 @@ def listOfLocals():
frame = gdb.selected_frame() frame = gdb.selected_frame()
#warn("FRAME %s: " % frame) #warn("FRAME %s: " % frame)
except RuntimeError: except RuntimeError:
return "" return []
items = [] items = []
if gdb.VERSION.startswith("6.8.50.2009"): if isGoodGdb():
# archer-tromey-python # archer-tromey-python
block = frame.block() block = frame.block()
while True: while True:
@@ -77,9 +81,11 @@ def listOfLocals():
block = block.superblock block = block.superblock
else: else:
# Assuming gdb 7.0 release. # Assuming gdb 7.0 release or 6.8-symbianelf.
file = tempfile.mkstemp(prefix="gdbpy_") file = tempfile.mkstemp(prefix="gdbpy_")
filename = file[1] filename = file[1]
gdb.execute("set logging off")
gdb.execute("set logging redirect off")
gdb.execute("set logging file %s" % filename) gdb.execute("set logging file %s" % filename)
gdb.execute("set logging redirect on") gdb.execute("set logging redirect on")
gdb.execute("set logging on") gdb.execute("set logging on")

View File

@@ -1244,11 +1244,16 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
// signal-meaning="Trace/breakpoint trap",thread-id="2", // signal-meaning="Trace/breakpoint trap",thread-id="2",
// frame={addr="0x7c91120f",func="ntdll!DbgUiConnectToDbg", // frame={addr="0x7c91120f",func="ntdll!DbgUiConnectToDbg",
// args=[],from="C:\\WINDOWS\\system32\\ntdll.dll"} // args=[],from="C:\\WINDOWS\\system32\\ntdll.dll"}
//if (reason == "signal-received" // also seen on gdb 6.8-symbianelf without qXfer:libraries:read+;
// && data.findChild("signal-name").data() == "SIGTRAP") { // FIXME: remote.c parses "loaded" reply. It should be turning
// continueInferiorInternal(); // that into a TARGET_WAITKIND_LOADED. Does it?
// return; // The bandaid here has the problem that it breaks for 'next' over a
//} // statement that indirectly loads shared libraries
if (reason == "signal-received"
&& data.findChild("signal-name").data() == "SIGTRAP") {
continueInferiorInternal();
return;
}
// jump over well-known frames // jump over well-known frames
static int stepCounter = 0; static int stepCounter = 0;

View File

@@ -253,6 +253,7 @@ private: ////////// Gdb Command Management //////////
CommandsDoneCallback m_commandsDoneCallback; CommandsDoneCallback m_commandsDoneCallback;
QList<GdbCommand> m_commandsToRunOnTemporaryBreak; QList<GdbCommand> m_commandsToRunOnTemporaryBreak;
int gdbVersion() const { return m_gdbVersion; }
private: ////////// Gdb Output, State & Capability Handling ////////// private: ////////// Gdb Output, State & Capability Handling //////////

View File

@@ -147,6 +147,7 @@ void Snapshot::reset()
memory.clear(); memory.clear();
for (int i = 0; i < RegisterCount; ++i) for (int i = 0; i < RegisterCount; ++i)
registers[i] = 0; registers[i] = 0;
registerValid = false;
wantedMemory = MemoryRange(); wantedMemory = MemoryRange();
} }
@@ -197,9 +198,11 @@ TrkGdbAdapter::TrkGdbAdapter(GdbEngine *engine, const TrkOptionsPtr &options) :
m_running(false), m_running(false),
m_trkDevice(new trk::TrkDevice), m_trkDevice(new trk::TrkDevice),
m_gdbAckMode(true), m_gdbAckMode(true),
m_verbose(0), m_verbose(0)
m_bufferedMemoryRead(true)
{ {
m_bufferedMemoryRead = false;
m_bufferedMemoryRead = true;
const QByteArray trkVerbose = qgetenv("QTC_TRK_VERBOSE"); const QByteArray trkVerbose = qgetenv("QTC_TRK_VERBOSE");
if (!trkVerbose.isEmpty()) { if (!trkVerbose.isEmpty()) {
bool ok; bool ok;
@@ -210,6 +213,7 @@ TrkGdbAdapter::TrkGdbAdapter(GdbEngine *engine, const TrkOptionsPtr &options) :
m_gdbServer = 0; m_gdbServer = 0;
m_gdbConnection = 0; m_gdbConnection = 0;
m_snapshot.reset();
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
const DWORD portOffset = GetCurrentProcessId() % 100; const DWORD portOffset = GetCurrentProcessId() % 100;
#else #else
@@ -388,11 +392,11 @@ void TrkGdbAdapter::slotEmitDelayedInferiorStartFailed()
void TrkGdbAdapter::logMessage(const QString &msg) void TrkGdbAdapter::logMessage(const QString &msg)
{ {
if (m_verbose) { if (m_verbose) {
#ifdef STANDALONE_RUNNER //#ifdef STANDALONE_RUNNER
emit output(msg); // emit output(msg);
#else //#else
m_engine->debugMessage(msg); m_engine->debugMessage("TRK LOG: " + msg);
#endif //#endif
} }
} }
@@ -629,9 +633,15 @@ void TrkGdbAdapter::handleGdbServerCommand(const QByteArray &cmd)
else if (cmd == "g") { else if (cmd == "g") {
// Read general registers. // Read general registers.
logMessage(msgGdbPacket(QLatin1String("Read registers"))); if (m_snapshot.registerValid) {
sendGdbServerAck(); logMessage(msgGdbPacket(QLatin1String("Read registers")));
reportRegisters(); sendGdbServerAck();
reportRegisters();
} else {
sendTrkMessage(0x12,
TrkCB(handleAndReportReadRegisters),
trkReadRegistersMessage());
}
} }
else if (cmd.startsWith("Hc")) { else if (cmd.startsWith("Hc")) {
@@ -692,21 +702,27 @@ void TrkGdbAdapter::handleGdbServerCommand(const QByteArray &cmd)
sendGdbServerAck(); sendGdbServerAck();
bool ok = false; bool ok = false;
const uint registerNumber = cmd.mid(1).toInt(&ok, 16); const uint registerNumber = cmd.mid(1).toInt(&ok, 16);
QByteArray logMsg = "Read Register"; if (m_snapshot.registerValid) {
if (registerNumber == RegisterPSGdb) { QByteArray logMsg = "Read Register";
QByteArray ba; if (registerNumber == RegisterPSGdb) {
appendInt(&ba, m_snapshot.registers[RegisterPSTrk], LittleEndian); QByteArray ba;
logMsg += dumpRegister(registerNumber, m_snapshot.registers[RegisterPSTrk]); appendInt(&ba, m_snapshot.registers[RegisterPSTrk], LittleEndian);
sendGdbServerMessage(ba.toHex(), logMsg); logMsg += dumpRegister(registerNumber, m_snapshot.registers[RegisterPSTrk]);
} else if (registerNumber < 16) { sendGdbServerMessage(ba.toHex(), logMsg);
QByteArray ba; } else if (registerNumber < 16) {
appendInt(&ba, m_snapshot.registers[registerNumber], LittleEndian); QByteArray ba;
logMsg += dumpRegister(registerNumber, m_snapshot.registers[registerNumber]); appendInt(&ba, m_snapshot.registers[registerNumber], LittleEndian);
sendGdbServerMessage(ba.toHex(), logMsg); logMsg += dumpRegister(registerNumber, m_snapshot.registers[registerNumber]);
sendGdbServerMessage(ba.toHex(), logMsg);
} else {
sendGdbServerMessage("0000", "read single unknown register #"
+ QByteArray::number(registerNumber));
//sendGdbServerMessage("E01", "read single unknown register");
}
} else { } else {
sendGdbServerMessage("0000", "read single unknown register #" sendTrkMessage(0x12,
+ QByteArray::number(registerNumber)); TrkCB(handleAndReportReadRegister),
//sendGdbServerMessage("E01", "read single unknown register"); trkReadRegistersMessage(), registerNumber);
} }
} }
@@ -815,18 +831,42 @@ void TrkGdbAdapter::handleGdbServerCommand(const QByteArray &cmd)
else if (cmd.startsWith("qXfer:features:read:target.xml:")) { else if (cmd.startsWith("qXfer:features:read:target.xml:")) {
// $qXfer:features:read:target.xml:0,7ca#46...Ack // $qXfer:features:read:target.xml:0,7ca#46...Ack
sendGdbServerAck(); sendGdbServerAck();
sendGdbServerMessage("l<target><architecture>symbianelf</architecture></target>"); //sendGdbServerMessage("l<target><architecture>symbianelf</architecture></target>");
sendGdbServerMessage("l<target><architecture>arm</architecture></target>");
//sendGdbServerMessage("l<target><architecture>arm-none-symbianelf</architecture></target>");
}
else if (cmd == "qfThreadInfo") {
// That's the _first_ query package.
sendGdbServerAck();
if (!m_session.threads.isEmpty()) {
QByteArray response = "m";
// FIXME: Limit packet length by using qsThreadInfo packages?
qDebug() << "CURRENT THREAD: " << m_session.tid;
response += hexNumber(m_session.tid);
sendGdbServerMessage(response, "thread information transfered");
} else {
sendGdbServerMessage("l", "thread information transfer finished");
}
}
else if (cmd == "qsThreadInfo") {
// That's a following query package
sendGdbServerAck();
sendGdbServerMessage("l", "thread information transfer finished");
} }
else if (cmd.startsWith("qXfer:libraries:read")) { else if (cmd.startsWith("qXfer:libraries:read")) {
sendGdbServerAck(); sendGdbServerAck();
/* QByteArray response = "l<library-list>";
<library-list> for (int i = 0; i != m_session.libraries.size(); ++i) {
<library name="/lib/libc.so.6"> const Library &lib = m_session.libraries.at(i);
<segment address="0x10000000"/> response += "<library name=\"" + lib.name + "\">";
</library> response += "<segment address=\"0x" + hexNumber(lib.codeseg) + "\"/>";
</library-list> response += "</library>";
i */ }
response += "</library-list>";
sendGdbServerMessage(response, "library information transfered");
} }
else if (cmd == "QStartNoAckMode") { else if (cmd == "QStartNoAckMode") {
@@ -855,6 +895,13 @@ i */
sendTrkMessage(0x19, TrkCB(handleStepInto), ba, "Step range"); sendTrkMessage(0x19, TrkCB(handleStepInto), ba, "Step range");
} }
else if (cmd.startsWith('T')) {
// FIXME: check whether thread is alive
sendGdbServerAck();
sendGdbServerMessage("OK"); // pretend all is well
//sendGdbServerMessage("E nn");
}
else if (cmd == "vCont?") { else if (cmd == "vCont?") {
// actions supported by the vCont packet // actions supported by the vCont packet
sendGdbServerAck(); sendGdbServerAck();
@@ -908,7 +955,7 @@ i */
} }
else if (cmd.startsWith("qPart:") || cmd.startsWith("qXfer:")) { else if (cmd.startsWith("qPart:") || cmd.startsWith("qXfer:")) {
QByteArray data = cmd.mid(1 + cmd.indexOf(':')); QByteArray data = cmd.mid(1 + cmd.indexOf(':'));
// "qPart:auxv:read::0,147": Read OS auxiliary data (see info aux) // "qPart:auxv:read::0,147": Read OS auxiliary data (see info aux)
bool handled = false; bool handled = false;
if (data.startsWith("auxv:read::")) { if (data.startsWith("auxv:read::")) {
@@ -928,6 +975,7 @@ i */
} }
} }
} // auxv read } // auxv read
if (!handled) { if (!handled) {
const QString msg = QLatin1String("FIXME unknown 'XFER'-request: ") const QString msg = QLatin1String("FIXME unknown 'XFER'-request: ")
+ QString::fromAscii(cmd); + QString::fromAscii(cmd);
@@ -1136,7 +1184,7 @@ void TrkGdbAdapter::handleDeleteProcess2(const TrkResult &result)
void TrkGdbAdapter::handleReadRegisters(const TrkResult &result) void TrkGdbAdapter::handleReadRegisters(const TrkResult &result)
{ {
logMessage(" RESULT: " + result.toString()); logMessage(" REGISTER RESULT: " + result.toString());
// [80 0B 00 00 00 00 00 C9 24 FF BC 00 00 00 00 00 // [80 0B 00 00 00 00 00 C9 24 FF BC 00 00 00 00 00
// 60 00 00 00 00 00 00 78 67 79 70 00 00 00 00 00...] // 60 00 00 00 00 00 00 78 67 79 70 00 00 00 00 00...]
if (result.errorCode()) { if (result.errorCode()) {
@@ -1146,6 +1194,7 @@ void TrkGdbAdapter::handleReadRegisters(const TrkResult &result)
const char *data = result.data.data() + 1; // Skip ok byte const char *data = result.data.data() + 1; // Skip ok byte
for (int i = 0; i < RegisterCount; ++i) for (int i = 0; i < RegisterCount; ++i)
m_snapshot.registers[i] = extractInt(data + 4 * i); m_snapshot.registers[i] = extractInt(data + 4 * i);
m_snapshot.registerValid = true;
} }
void TrkGdbAdapter::handleWriteRegister(const TrkResult &result) void TrkGdbAdapter::handleWriteRegister(const TrkResult &result)
@@ -1176,6 +1225,34 @@ void TrkGdbAdapter::reportRegisters()
sendGdbServerMessage(ba, logMsg); sendGdbServerMessage(ba, logMsg);
} }
void TrkGdbAdapter::handleAndReportReadRegisters(const TrkResult &result)
{
handleReadRegisters(result);
reportRegisters();
}
void TrkGdbAdapter::handleAndReportReadRegister(const TrkResult &result)
{
handleReadRegisters(result);
int registerNumber = result.cookie.toInt();
QByteArray logMsg = "Read Register";
if (registerNumber == RegisterPSGdb) {
QByteArray ba;
appendInt(&ba, m_snapshot.registers[RegisterPSTrk], LittleEndian);
logMsg += dumpRegister(registerNumber, m_snapshot.registers[RegisterPSTrk]);
sendGdbServerMessage(ba.toHex(), logMsg);
} else if (registerNumber < 16) {
QByteArray ba;
appendInt(&ba, m_snapshot.registers[registerNumber], LittleEndian);
logMsg += dumpRegister(registerNumber, m_snapshot.registers[registerNumber]);
sendGdbServerMessage(ba.toHex(), logMsg);
} else {
sendGdbServerMessage("0000", "read single unknown register #"
+ QByteArray::number(registerNumber));
//sendGdbServerMessage("E01", "read single unknown register");
}
}
static void appendRegister(QByteArray *ba, uint regno, uint value) static void appendRegister(QByteArray *ba, uint regno, uint value)
{ {
ba->append(hexNumber(regno, 2)); ba->append(hexNumber(regno, 2));
@@ -1312,7 +1389,7 @@ void TrkGdbAdapter::tryAnswerGdbMemoryRequest(bool buffered)
logMessage(_("Requesting buffered memory %1 bytes from 0x%2") logMessage(_("Requesting buffered memory %1 bytes from 0x%2")
.arg(MemoryChunkSize).arg(blockaddr, 0, 16)); .arg(MemoryChunkSize).arg(blockaddr, 0, 16));
MemoryRange range(blockaddr, blockaddr + MemoryChunkSize); MemoryRange range(blockaddr, blockaddr + MemoryChunkSize);
MEMORY_DEBUGX(" FETCH MEMORY : " << range); MEMORY_DEBUG(" FETCH MEMORY : " << range);
sendTrkMessage(0x10, TrkCB(handleReadMemoryBuffered), sendTrkMessage(0x10, TrkCB(handleReadMemoryBuffered),
trkReadMemoryMessage(range), trkReadMemoryMessage(range),
QVariant::fromValue(range)); QVariant::fromValue(range));
@@ -1323,7 +1400,7 @@ void TrkGdbAdapter::tryAnswerGdbMemoryRequest(bool buffered)
sendTrkMessage(0x10, TrkCB(handleReadMemoryUnbuffered), sendTrkMessage(0x10, TrkCB(handleReadMemoryUnbuffered),
trkReadMemoryMessage(needed), trkReadMemoryMessage(needed),
QVariant::fromValue(needed)); QVariant::fromValue(needed));
MEMORY_DEBUGX(" FETCH MEMORY : " << needed); MEMORY_DEBUG(" FETCH MEMORY : " << needed);
} }
} }

View File

@@ -92,6 +92,7 @@ struct Snapshot
void insertMemory(const MemoryRange &range, const QByteArray &ba); void insertMemory(const MemoryRange &range, const QByteArray &ba);
uint registers[RegisterCount]; uint registers[RegisterCount];
bool registerValid;
typedef QMap<MemoryRange, QByteArray> Memory; typedef QMap<MemoryRange, QByteArray> Memory;
Memory memory; Memory memory;
@@ -204,6 +205,8 @@ private:
void handleDeleteProcess(const TrkResult &result); void handleDeleteProcess(const TrkResult &result);
void handleDeleteProcess2(const TrkResult &result); void handleDeleteProcess2(const TrkResult &result);
void handleAndReportCreateProcess(const TrkResult &result); void handleAndReportCreateProcess(const TrkResult &result);
void handleAndReportReadRegisters(const TrkResult &result);
void handleAndReportReadRegister(const TrkResult &result);
void handleAndReportReadRegistersAfterStop(const TrkResult &result); void handleAndReportReadRegistersAfterStop(const TrkResult &result);
void reportRegisters(); void reportRegisters();
QByteArray memoryReadLogMessage(uint addr, const QByteArray &ba) const; QByteArray memoryReadLogMessage(uint addr, const QByteArray &ba) const;