diff options
author | Friedemann Kleint <Friedemann.Kleint@nokia.com> | 2011-02-28 14:33:35 +0100 |
---|---|---|
committer | Friedemann Kleint <Friedemann.Kleint@nokia.com> | 2011-02-28 14:34:42 +0100 |
commit | e8d12ae4643ae735488ad9d5daf838ad8819b88e (patch) | |
tree | f6201306dc0789079232de976563d93f1dc1d95c /src | |
parent | 6061f4bb48fb7db7684de5caad1c9d6962a97104 (diff) | |
download | qt-creator-e8d12ae4643ae735488ad9d5daf838ad8819b88e.tar.gz |
Debugger[CDB]: Add memory editing.
Add infrastructure for custom special stops with data.
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/debugger/cdb/cdbengine.cpp | 44 | ||||
-rw-r--r-- | src/plugins/debugger/cdb/cdbengine.h | 9 | ||||
-rw-r--r-- | src/plugins/debugger/cdb/cdbparsehelpers.cpp | 12 | ||||
-rw-r--r-- | src/plugins/debugger/cdb/cdbparsehelpers.h | 2 |
4 files changed, 65 insertions, 2 deletions
diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 9af511892b..ef7468200f 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -173,10 +173,20 @@ struct MemoryViewCookie quint64 length; }; +struct MemoryChangeCookie +{ + explicit MemoryChangeCookie(quint64 addr = 0, const QByteArray &d = QByteArray()) : + address(addr), data(d) {} + + quint64 address; + QByteArray data; +}; + } // namespace Internal } // namespace Debugger Q_DECLARE_METATYPE(Debugger::Internal::MemoryViewCookie) +Q_DECLARE_METATYPE(Debugger::Internal::MemoryChangeCookie) namespace Debugger { namespace Internal { @@ -451,6 +461,7 @@ void CdbEngine::init() m_extensionCommandQueue.clear(); m_extensionMessageBuffer.clear(); m_pendingBreakpointMap.clear(); + m_customSpecialStopData.clear(); QTC_ASSERT(m_process.state() != QProcess::Running, Utils::SynchronousProcess::stopProcess(m_process); ) } @@ -1087,6 +1098,13 @@ void CdbEngine::interruptInferior() } } +void CdbEngine::doInterruptInferiorCustomSpecialStop(const QVariant &v) +{ + if (m_specialStopMode == NoSpecialStop) + doInterruptInferior(CustomSpecialStop); + m_customSpecialStopData.push_back(v); +} + void CdbEngine::doInterruptInferior(SpecialStopMode sm) { #ifdef Q_OS_WIN @@ -1446,6 +1464,17 @@ void CdbEngine::fetchMemory(MemoryAgent *agent, QObject *editor, quint64 addr, q postExtensionCommand("memory", args, 0, &CdbEngine::handleMemory, 0, cookie); } +void CdbEngine::changeMemory(Internal::MemoryAgent *, QObject *, quint64 addr, const QByteArray &data) +{ + QTC_ASSERT(!data.isEmpty(), return; ) + if (!m_accessible) { + const MemoryChangeCookie cookie(addr, data); + doInterruptInferiorCustomSpecialStop(qVariantFromValue(cookie)); + } else { + postCommand(cdbWriteMemoryCommand(addr, data), 0); + } +} + void CdbEngine::handleMemory(const CdbExtensionCommandPtr &command) { QTC_ASSERT(qVariantCanConvert<MemoryViewCookie>(command->cookie), return;) @@ -1782,6 +1811,12 @@ void CdbEngine::handleSessionIdle(const QByteArray &messageBA) case SpecialStopGetWidgetAt: postWidgetAtCommand(); return; + case CustomSpecialStop: + foreach (const QVariant &data, m_customSpecialStopData) + handleCustomSpecialStop(data); + m_customSpecialStopData.clear(); + doContinueInferior(); + return; case NoSpecialStop: break; } @@ -2560,5 +2595,14 @@ void CdbEngine::postWidgetAtCommand() postExtensionCommand("widgetat", arguments, 0, &CdbEngine::handleWidgetAt, 0); } +void CdbEngine::handleCustomSpecialStop(const QVariant &v) +{ + if (qVariantCanConvert<MemoryChangeCookie>(v)) { + const MemoryChangeCookie changeData = qVariantValue<MemoryChangeCookie>(v); + postCommand(cdbWriteMemoryCommand(changeData.address, changeData.data), 0); + return; + } +} + } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/cdb/cdbengine.h b/src/plugins/debugger/cdb/cdbengine.h index 3d8de9f91f..cb7a3d73fe 100644 --- a/src/plugins/debugger/cdb/cdbengine.h +++ b/src/plugins/debugger/cdb/cdbengine.h @@ -39,7 +39,7 @@ #include <QtCore/QSharedPointer> #include <QtCore/QProcess> -#include <QtCore/QVariant> +#include <QtCore/QVariantList> #include <QtCore/QMap> #include <QtCore/QTime> @@ -123,6 +123,7 @@ public: virtual void fetchDisassembler(DisassemblerAgent *agent); virtual void fetchMemory(MemoryAgent *, QObject *, quint64 addr, quint64 length); + virtual void changeMemory(Internal::MemoryAgent *, QObject *, quint64 addr, const QByteArray &data); virtual void reloadModules(); virtual void loadSymbols(const QString &moduleName); @@ -168,7 +169,8 @@ private: { NoSpecialStop, SpecialStopSynchronizeBreakpoints, - SpecialStopGetWidgetAt + SpecialStopGetWidgetAt, + CustomSpecialStop // Associated with m_specialStopData, handleCustomSpecialStop() }; enum ParseStackResultFlags // Flags returned by parseStackTrace { @@ -188,12 +190,14 @@ private: void handleSessionInaccessible(unsigned long cdbExState); void handleSessionIdle(const QByteArray &message); void doInterruptInferior(SpecialStopMode sm); + void doInterruptInferiorCustomSpecialStop(const QVariant &v); void doContinueInferior(); inline void parseOutputLine(QByteArray line); inline bool isCdbProcessRunning() const { return m_process.state() != QProcess::NotRunning; } bool canInterruptInferior() const; void syncOperateByInstruction(bool operateByInstruction); void postWidgetAtCommand(); + void handleCustomSpecialStop(const QVariant &v); // Builtin commands void dummyHandler(const CdbBuiltinCommandPtr &); @@ -253,6 +257,7 @@ private: PendingBreakPointMap m_pendingBreakpointMap; QHash<QString, QString> m_fileNameModuleHash; bool m_ignoreCdbOutput; + QVariantList m_customSpecialStopData; }; } // namespace Internal diff --git a/src/plugins/debugger/cdb/cdbparsehelpers.cpp b/src/plugins/debugger/cdb/cdbparsehelpers.cpp index 5e3c7b0739..28d9c88d1b 100644 --- a/src/plugins/debugger/cdb/cdbparsehelpers.cpp +++ b/src/plugins/debugger/cdb/cdbparsehelpers.cpp @@ -252,6 +252,18 @@ BreakpointId parseBreakPoint(const GdbMi &gdbmi, BreakpointResponse *r, return id; } +QByteArray cdbWriteMemoryCommand(quint64 addr, const QByteArray &data) +{ + QByteArray cmd; + ByteArrayInputStream str(cmd); + str.setIntegerBase(16); + str << "f " << addr << " L" << data.size(); + const int count = data.size(); + for (int i = 0 ; i < count ; i++ ) + str << ' ' << int(data.at(i)); + return cmd; +} + QString debugByteArray(const QByteArray &a) { QString rc; diff --git a/src/plugins/debugger/cdb/cdbparsehelpers.h b/src/plugins/debugger/cdb/cdbparsehelpers.h index b65625b984..0f8f8035e5 100644 --- a/src/plugins/debugger/cdb/cdbparsehelpers.h +++ b/src/plugins/debugger/cdb/cdbparsehelpers.h @@ -65,6 +65,8 @@ BreakpointId parseBreakPoint(const GdbMi &gdbmi, BreakpointResponse *r, QString QByteArray fixCdbIntegerValue(QByteArray t, bool stripLeadingZeros = false, int *basePtr = 0); // Convert a CDB integer value into quint64 or int64 QVariant cdbIntegerValue(const QByteArray &t); +// Write memory (f ...). +QByteArray cdbWriteMemoryCommand(quint64 addr, const QByteArray &data); QString debugByteArray(const QByteArray &a); QString StringFromBase64EncodedUtf16(const QByteArray &a); |