summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/plugins/debugger/cdb/cdbengine.cpp44
-rw-r--r--src/plugins/debugger/cdb/cdbengine.h9
-rw-r--r--src/plugins/debugger/cdb/cdbparsehelpers.cpp12
-rw-r--r--src/plugins/debugger/cdb/cdbparsehelpers.h2
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);