diff --git a/share/qtcreator/gdbmacros/dumper.py b/share/qtcreator/gdbmacros/dumper.py index 380189c75b690fe8cee3bdee15bc6265364fbbd5..072ba5b590a0f8f1360e50a69f8c0e42a023d068 100644 --- a/share/qtcreator/gdbmacros/dumper.py +++ b/share/qtcreator/gdbmacros/dumper.py @@ -26,8 +26,12 @@ def qmin(n, m): return n return m +def isGoodGdb(): + return gdb.VERSION.startswith("6.8.50.2009") \ + and gdb.VERSION != "6.8.50.20090630-cvs" + def parseAndEvaluate(exp): - if gdb.VERSION.startswith("6.8.50.2009"): + if isGoodGdb(): return gdb.parse_and_eval(exp) # Work around non-existing gdb.parse_and_eval as in released 7.0 gdb.execute("set logging redirect on") @@ -41,10 +45,10 @@ def listOfLocals(): frame = gdb.selected_frame() #warn("FRAME %s: " % frame) except RuntimeError: - return "" + return [] items = [] - if gdb.VERSION.startswith("6.8.50.2009"): + if isGoodGdb(): # archer-tromey-python block = frame.block() while True: @@ -77,9 +81,11 @@ def listOfLocals(): block = block.superblock else: - # Assuming gdb 7.0 release. + # Assuming gdb 7.0 release or 6.8-symbianelf. file = tempfile.mkstemp(prefix="gdbpy_") 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 redirect on") gdb.execute("set logging on") diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index b7c8c006050393bf5968b2024ffc147ff6a32d6d..4c0ca907344e4b0ea2cfff796299117ee8805476 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -1244,11 +1244,16 @@ void GdbEngine::handleStopResponse(const GdbMi &data) // signal-meaning="Trace/breakpoint trap",thread-id="2", // frame={addr="0x7c91120f",func="ntdll!DbgUiConnectToDbg", // args=[],from="C:\\WINDOWS\\system32\\ntdll.dll"} - //if (reason == "signal-received" - // && data.findChild("signal-name").data() == "SIGTRAP") { - // continueInferiorInternal(); - // return; - //} + // also seen on gdb 6.8-symbianelf without qXfer:libraries:read+; + // FIXME: remote.c parses "loaded" reply. It should be turning + // that into a TARGET_WAITKIND_LOADED. Does it? + // 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 static int stepCounter = 0; diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index 06312b3ed113988fab0686449d0e4387fe871ffe..3a1bd2c945a95b6c88e29c500a5e16e8d89dbfbe 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -253,6 +253,7 @@ private: ////////// Gdb Command Management ////////// CommandsDoneCallback m_commandsDoneCallback; QList<GdbCommand> m_commandsToRunOnTemporaryBreak; + int gdbVersion() const { return m_gdbVersion; } private: ////////// Gdb Output, State & Capability Handling ////////// diff --git a/src/plugins/debugger/gdb/trkgdbadapter.cpp b/src/plugins/debugger/gdb/trkgdbadapter.cpp index 3eab98ab2e785c94feb0491dab28ca542c8143be..a176981d7d78e728312c1a389f74292bb039184c 100644 --- a/src/plugins/debugger/gdb/trkgdbadapter.cpp +++ b/src/plugins/debugger/gdb/trkgdbadapter.cpp @@ -147,6 +147,7 @@ void Snapshot::reset() memory.clear(); for (int i = 0; i < RegisterCount; ++i) registers[i] = 0; + registerValid = false; wantedMemory = MemoryRange(); } @@ -197,9 +198,11 @@ TrkGdbAdapter::TrkGdbAdapter(GdbEngine *engine, const TrkOptionsPtr &options) : m_running(false), m_trkDevice(new trk::TrkDevice), m_gdbAckMode(true), - m_verbose(0), - m_bufferedMemoryRead(true) + m_verbose(0) { + m_bufferedMemoryRead = false; + m_bufferedMemoryRead = true; + const QByteArray trkVerbose = qgetenv("QTC_TRK_VERBOSE"); if (!trkVerbose.isEmpty()) { bool ok; @@ -210,6 +213,7 @@ TrkGdbAdapter::TrkGdbAdapter(GdbEngine *engine, const TrkOptionsPtr &options) : m_gdbServer = 0; m_gdbConnection = 0; + m_snapshot.reset(); #ifdef Q_OS_WIN const DWORD portOffset = GetCurrentProcessId() % 100; #else @@ -388,11 +392,11 @@ void TrkGdbAdapter::slotEmitDelayedInferiorStartFailed() void TrkGdbAdapter::logMessage(const QString &msg) { if (m_verbose) { -#ifdef STANDALONE_RUNNER - emit output(msg); -#else - m_engine->debugMessage(msg); -#endif +//#ifdef STANDALONE_RUNNER +// emit output(msg); +//#else + m_engine->debugMessage("TRK LOG: " + msg); +//#endif } } @@ -629,9 +633,15 @@ void TrkGdbAdapter::handleGdbServerCommand(const QByteArray &cmd) else if (cmd == "g") { // Read general registers. - logMessage(msgGdbPacket(QLatin1String("Read registers"))); - sendGdbServerAck(); - reportRegisters(); + if (m_snapshot.registerValid) { + logMessage(msgGdbPacket(QLatin1String("Read registers"))); + sendGdbServerAck(); + reportRegisters(); + } else { + sendTrkMessage(0x12, + TrkCB(handleAndReportReadRegisters), + trkReadRegistersMessage()); + } } else if (cmd.startsWith("Hc")) { @@ -692,21 +702,27 @@ void TrkGdbAdapter::handleGdbServerCommand(const QByteArray &cmd) sendGdbServerAck(); bool ok = false; const uint registerNumber = cmd.mid(1).toInt(&ok, 16); - 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); + if (m_snapshot.registerValid) { + 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"); + } } else { - sendGdbServerMessage("0000", "read single unknown register #" - + QByteArray::number(registerNumber)); - //sendGdbServerMessage("E01", "read single unknown register"); + sendTrkMessage(0x12, + TrkCB(handleAndReportReadRegister), + trkReadRegistersMessage(), registerNumber); } } @@ -815,18 +831,42 @@ void TrkGdbAdapter::handleGdbServerCommand(const QByteArray &cmd) else if (cmd.startsWith("qXfer:features:read:target.xml:")) { // $qXfer:features:read:target.xml:0,7ca#46...Ack 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")) { sendGdbServerAck(); - /* - <library-list> - <library name="/lib/libc.so.6"> - <segment address="0x10000000"/> - </library> - </library-list> -i */ + QByteArray response = "l<library-list>"; + for (int i = 0; i != m_session.libraries.size(); ++i) { + const Library &lib = m_session.libraries.at(i); + response += "<library name=\"" + lib.name + "\">"; + response += "<segment address=\"0x" + hexNumber(lib.codeseg) + "\"/>"; + response += "</library>"; + } + response += "</library-list>"; + sendGdbServerMessage(response, "library information transfered"); } else if (cmd == "QStartNoAckMode") { @@ -855,6 +895,13 @@ i */ 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?") { // actions supported by the vCont packet sendGdbServerAck(); @@ -908,7 +955,7 @@ i */ } 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) bool handled = false; if (data.startsWith("auxv:read::")) { @@ -928,6 +975,7 @@ i */ } } } // auxv read + if (!handled) { const QString msg = QLatin1String("FIXME unknown 'XFER'-request: ") + QString::fromAscii(cmd); @@ -1136,7 +1184,7 @@ void TrkGdbAdapter::handleDeleteProcess2(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 // 60 00 00 00 00 00 00 78 67 79 70 00 00 00 00 00...] if (result.errorCode()) { @@ -1146,6 +1194,7 @@ void TrkGdbAdapter::handleReadRegisters(const TrkResult &result) const char *data = result.data.data() + 1; // Skip ok byte for (int i = 0; i < RegisterCount; ++i) m_snapshot.registers[i] = extractInt(data + 4 * i); + m_snapshot.registerValid = true; } void TrkGdbAdapter::handleWriteRegister(const TrkResult &result) @@ -1176,6 +1225,34 @@ void TrkGdbAdapter::reportRegisters() 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) { ba->append(hexNumber(regno, 2)); @@ -1312,7 +1389,7 @@ void TrkGdbAdapter::tryAnswerGdbMemoryRequest(bool buffered) logMessage(_("Requesting buffered memory %1 bytes from 0x%2") .arg(MemoryChunkSize).arg(blockaddr, 0, 16)); MemoryRange range(blockaddr, blockaddr + MemoryChunkSize); - MEMORY_DEBUGX(" FETCH MEMORY : " << range); + MEMORY_DEBUG(" FETCH MEMORY : " << range); sendTrkMessage(0x10, TrkCB(handleReadMemoryBuffered), trkReadMemoryMessage(range), QVariant::fromValue(range)); @@ -1323,7 +1400,7 @@ void TrkGdbAdapter::tryAnswerGdbMemoryRequest(bool buffered) sendTrkMessage(0x10, TrkCB(handleReadMemoryUnbuffered), trkReadMemoryMessage(needed), QVariant::fromValue(needed)); - MEMORY_DEBUGX(" FETCH MEMORY : " << needed); + MEMORY_DEBUG(" FETCH MEMORY : " << needed); } } diff --git a/src/plugins/debugger/gdb/trkgdbadapter.h b/src/plugins/debugger/gdb/trkgdbadapter.h index c59894ffd09c73f57f8d72d4dbe8ac1a863b4781..d886ad4f33c3c4e2a6bf726771ec26dc0248f159 100644 --- a/src/plugins/debugger/gdb/trkgdbadapter.h +++ b/src/plugins/debugger/gdb/trkgdbadapter.h @@ -92,6 +92,7 @@ struct Snapshot void insertMemory(const MemoryRange &range, const QByteArray &ba); uint registers[RegisterCount]; + bool registerValid; typedef QMap<MemoryRange, QByteArray> Memory; Memory memory; @@ -204,6 +205,8 @@ private: void handleDeleteProcess(const TrkResult &result); void handleDeleteProcess2(const TrkResult &result); void handleAndReportCreateProcess(const TrkResult &result); + void handleAndReportReadRegisters(const TrkResult &result); + void handleAndReportReadRegister(const TrkResult &result); void handleAndReportReadRegistersAfterStop(const TrkResult &result); void reportRegisters(); QByteArray memoryReadLogMessage(uint addr, const QByteArray &ba) const;