forked from qt-creator/qt-creator
Debugger[CDB]: Add memory editing.
Add infrastructure for custom special stops with data.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user