work save

This commit is contained in:
Roy Qu 2024-03-10 09:56:20 +08:00
parent 1f8fa070c8
commit 6ba9cbb78b
8 changed files with 196 additions and 78 deletions

View File

@ -86,3 +86,8 @@ void DAPDebuggerClient::run()
emit processFailed(mProcess->error());
}
}
DebuggerType DAPDebuggerClient::clientType()
{
return DebuggerType::DAP;
}

View File

@ -34,6 +34,7 @@ public:
void postCommand(const QString &Command, const QString &Params, DebugCommandSource Source) override;
void registerInferiorStoppedCommand(const QString &Command, const QString &Params) override;
void stopDebug() override;
DebuggerType clientType() override;
protected:
void runNextCmd() override;

View File

@ -159,7 +159,7 @@ bool Debugger::start(int compilerSetIndex, const QString& inferior, const QStrin
mTarget->waitStart();
}
//delete when thread finished
mClient = new GDBMIDebuggerClient(this);
mClient = new GDBMIDebuggerClient(this, debuggerType());
mClient->addBinDirs(binDirs);
mClient->addBinDir(pSettings->dirs().appDir());
mClient->setDebuggerPath(debuggerPath);
@ -270,10 +270,10 @@ void Debugger::updateRegisterValues(const QHash<int, QString> &values)
void Debugger::refreshAll()
{
refreshWatchVars();
if (mExecuting && mClient)
if (mClient)
mClient->refreshStackVariables();
if (memoryModel()->startAddress()>0
&& mExecuting && mClient)
&& mClient)
mClient->readMemory(
memoryModel()->startAddress(),
pSettings->debugger().memoryViewRows(),
@ -291,16 +291,9 @@ std::shared_ptr<WatchModel> Debugger::watchModel() const
return mWatchModel;
}
void Debugger::sendCommand(const QString &command, const QString &params, DebugCommandSource source)
{
if (mExecuting && mClient) {
mClient->postCommand(command,params,source);
}
}
bool Debugger::commandRunning()
{
if (mExecuting && mClient) {
if (mClient) {
return mClient->commandRunning();
}
return false;
@ -308,7 +301,7 @@ bool Debugger::commandRunning()
bool Debugger::inferiorRunning()
{
if (mExecuting && mClient) {
if (mClient) {
return mClient->inferiorRunning();
}
return false;
@ -316,7 +309,7 @@ bool Debugger::inferiorRunning()
void Debugger::interrupt()
{
if (mExecuting && mClient) {
if (mClient) {
mClient->interrupt();
}
}
@ -441,7 +434,7 @@ PBreakpoint Debugger::breakpointAt(int line, const Editor *editor, int *index)
void Debugger::setBreakPointCondition(int index, const QString &condition, bool forProject)
{
PBreakpoint breakpoint=mBreakpointModel->setBreakPointCondition(index,condition, forProject);
if (mExecuting && mClient)
if (mClient)
mClient->setBreakpointCondition(breakpoint);
}
@ -494,7 +487,7 @@ void Debugger::loadForProject(const QString &filename, const QString &projectFol
void Debugger::addWatchpoint(const QString &expression)
{
QString s=expression.trimmed();
if (mExecuting && mClient) {
if (mClient) {
mClient->addWatchpoint(expression);
}
}
@ -536,31 +529,29 @@ void Debugger::modifyWatchVarExpression(const QString &oldExpr, const QString &n
var->name.clear();
var->children.clear();
if (mExecuting) {
sendWatchCommand(var);
}
sendWatchCommand(var);
}
}
void Debugger::refreshWatchVars()
{
if (mExecuting && mClient) {
if (mClient) {
sendAllWatchVarsToDebugger();
if (mDebuggerType==DebuggerType::LLDB_MI) {
for (PWatchVar var:mWatchModel->watchVars()) {
if (!var->name.isEmpty())
mClient->refreshWatchVar(var);
mClient->refreshWatch(var);
}
} else {
sendCommand("-var-update"," --all-values *");
mClient->refreshWatch();
}
}
}
void Debugger::fetchVarChildren(const QString &varName)
{
if (mExecuting) {
sendCommand("-var-list-children",varName);
if (mClient) {
mClient->fetchWatchVarChildren(varName);
}
}
@ -648,6 +639,12 @@ PWatchVar Debugger::watchVarAt(const QModelIndex &index)
return mWatchModel->findWatchVar(index);
}
void Debugger::evalExpression(const QString &expression)
{
if (mClient)
mClient->evalExpression(expression);
}
//void Debugger::notifyWatchVarUpdated(PWatchVar var)
//{
// mWatchModel->notifyUpdated(var);
@ -664,36 +661,20 @@ std::shared_ptr<BreakpointModel> Debugger::breakpointModel()
void Debugger::sendWatchCommand(PWatchVar var)
{
sendCommand("-var-create", var->expression);
if (mClient)
mClient->addWatch(var->expression);
}
void Debugger::sendRemoveWatchCommand(PWatchVar var)
{
sendCommand("-var-delete",QString("%1").arg(var->name));
if (mClient)
mClient->removeWatch(var);
}
void Debugger::sendBreakpointCommand(PBreakpoint breakpoint)
{
if (breakpoint && mExecuting) {
// break "filename":linenum
QString condition;
if (!breakpoint->condition.isEmpty()) {
condition = " -c " + breakpoint->condition;
}
QString filename = breakpoint->filename;
filename.replace('\\','/');
if (debuggerType()==DebuggerType::LLDB_MI) {
sendCommand("-break-insert",
QString("%1 \"%2:%3\"")
.arg(condition, filename)
.arg(breakpoint->line));
} else {
sendCommand("-break-insert",
QString("%1 --source \"%2\" --line %3")
.arg(condition,filename)
.arg(breakpoint->line));
}
}
if (mClient)
mClient->addBreakpoint(breakpoint);
}
void Debugger::sendClearBreakpointCommand(int index, bool forProject)
@ -703,14 +684,8 @@ void Debugger::sendClearBreakpointCommand(int index, bool forProject)
void Debugger::sendClearBreakpointCommand(PBreakpoint breakpoint)
{
// Debugger already running? Remove it from GDB
if (breakpoint && breakpoint->number>=0 && mExecuting) {
//clear "filename":linenum
QString filename = breakpoint->filename;
filename.replace('\\','/');
sendCommand("-break-delete",
QString("%1").arg(breakpoint->number));
}
if (mClient)
mClient->removeBreakpoint(breakpoint);
}
QJsonArray BreakpointModel::toJson(const QString& projectFolder)
@ -941,13 +916,15 @@ void Debugger::syncFinishedParsing()
void Debugger::setMemoryData(qulonglong address, unsigned char data)
{
sendCommand("-data-write-memory-bytes", QString("%1 \"%2\"").arg(address).arg(data,2,16,QChar('0')));
if (mClient)
mClient->writeMemory(address, data);
refreshAll();
}
void Debugger::setWatchVarValue(const QString &name, const QString &value)
{
sendCommand("-var-assign",QString("%1 %2").arg(name,value));
if (mClient)
mClient->writeWatchVar(name, value);
refreshAll();
}

View File

@ -303,8 +303,6 @@ public:
~Debugger();
// Play/pause
bool start(int compilerSetIndex, const QString& inferior, const QStringList& binDirs, const QString& sourceFile=QString());
void sendCommand(const QString& command, const QString& params,
DebugCommandSource source = DebugCommandSource::Other);
bool commandRunning();
bool inferiorRunning();
void interrupt();
@ -345,6 +343,10 @@ public:
PWatchVar findWatchVar(const QString& expression);
PWatchVar watchVarAt(const QModelIndex& index);
void refreshVars();
void evalExpression(const QString& expression);
// void notifyWatchVarUpdated(PWatchVar var);
std::shared_ptr<BacktraceModel> backtraceModel();
@ -493,13 +495,33 @@ public:
Debugger* debugger() { return mDebugger; }
virtual DebuggerType clientType() = 0;
//requests
virtual void interrupt() = 0;
virtual void refreshStackVariables() = 0;
virtual void readMemory(qulonglong startAddress, int rows, int cols) = 0;
virtual void setBreakpointCondition(PBreakpoint breakpoint) = 0;
virtual void writeMemory(qulonglong address, unsigned char data) = 0;
virtual void addBreakpoint(PBreakpoint breakpoint) = 0;
virtual void removeBreakpoint(PBreakpoint breakpoint) = 0;
virtual void addWatchpoint(const QString& watchExp) = 0;
virtual void refreshWatchVar(PWatchVar var) = 0;
virtual void setBreakpointCondition(PBreakpoint breakpoint) = 0;
virtual void addWatch(const QString& expression) = 0;
virtual void removeWatch(PWatchVar watchVar) = 0;
virtual void writeWatchVar(const QString& varName, const QString& value) = 0;
virtual void refreshWatch(PWatchVar var) = 0;
virtual void refreshWatch() = 0;
virtual void fetchWatchVarChildren(const QString& varName) = 0;
virtual void evalExpression(const QString& expression) = 0;
virtual void refreshFrame() = 0;
virtual void refreshRegisters() = 0;
virtual void disassembleCurrentFrame(bool blendMode) = 0;
signals:
void parseStarted();

View File

@ -26,8 +26,12 @@
const QRegularExpression GDBMIDebuggerClient::REGdbSourceLine("^(\\d)+\\s+in\\s+(.+)$");
GDBMIDebuggerClient::GDBMIDebuggerClient(Debugger *debugger, QObject *parent):
DebuggerClient(debugger, parent)
GDBMIDebuggerClient::GDBMIDebuggerClient(
Debugger *debugger,
DebuggerType clientType,
QObject *parent):
DebuggerClient{debugger, parent},
mClientType{clientType}
{
mProcess = std::make_shared<QProcess>();
mAsyncUpdated = false;
@ -61,6 +65,11 @@ void GDBMIDebuggerClient::stopDebug()
mStop = true;
}
DebuggerType GDBMIDebuggerClient::clientType()
{
return mClientType;
}
void GDBMIDebuggerClient::run()
{
mStop = false;
@ -867,12 +876,12 @@ const PDebugCommand &GDBMIDebuggerClient::currentCmd() const
void GDBMIDebuggerClient::interrupt()
{
postCommand("-exec-interrupt", "", DebugCommandSource::Other);
postCommand("-exec-interrupt", "");
}
void GDBMIDebuggerClient::refreshStackVariables()
{
postCommand("-stack-list-variables", "--all-values", DebugCommandSource::Other);
postCommand("-stack-list-variables", "--all-values");
}
void GDBMIDebuggerClient::readMemory(qulonglong startAddress, int rows, int cols)
@ -880,9 +889,47 @@ void GDBMIDebuggerClient::readMemory(qulonglong startAddress, int rows, int cols
postCommand("-data-read-memory",QString("%1 x 1 %2 %3 ")
.arg(startAddress)
.arg(rows)
.arg(cols),
DebugCommandSource::Other
);
.arg(cols));
}
void GDBMIDebuggerClient::writeMemory(qulonglong address, unsigned char data)
{
postCommand("-data-write-memory-bytes", QString("%1 \"%2\"").arg(address).arg(data,2,16,QChar('0')));
}
void GDBMIDebuggerClient::addBreakpoint(PBreakpoint breakpoint)
{
if (breakpoint) {
// break "filename":linenum
QString condition;
if (!breakpoint->condition.isEmpty()) {
condition = " -c " + breakpoint->condition;
}
QString filename = breakpoint->filename;
filename.replace('\\','/');
if (clientType()==DebuggerType::LLDB_MI) {
postCommand("-break-insert",
QString("%1 \"%2:%3\"")
.arg(condition, filename)
.arg(breakpoint->line));
} else {
postCommand("-break-insert",
QString("%1 --source \"%2\" --line %3")
.arg(condition,filename)
.arg(breakpoint->line));
}
}
}
void GDBMIDebuggerClient::removeBreakpoint(PBreakpoint breakpoint)
{
if (breakpoint && breakpoint->number>=0) {
//clear "filename":linenum
QString filename = breakpoint->filename;
filename.replace('\\','/');
postCommand("-break-delete",
QString("%1").arg(breakpoint->number));
}
}
void GDBMIDebuggerClient::setBreakpointCondition(PBreakpoint breakpoint)
@ -891,25 +938,72 @@ void GDBMIDebuggerClient::setBreakpointCondition(PBreakpoint breakpoint)
QString condition = breakpoint->condition;
if (condition.isEmpty()) {
postCommand("-break-condition",
QString("%1").arg(breakpoint->number), DebugCommandSource::Other);
QString("%1").arg(breakpoint->number));
} else {
postCommand("-break-condition",
QString("%1 %2").arg(breakpoint->number).arg(condition), DebugCommandSource::Other);
QString("%1 %2").arg(breakpoint->number).arg(condition));
}
}
void GDBMIDebuggerClient::addWatch(const QString &expression)
{
postCommand("-var-create", expression);
}
void GDBMIDebuggerClient::removeWatch(PWatchVar watchVar)
{
postCommand("-var-delete",QString("%1").arg(watchVar->name));
}
void GDBMIDebuggerClient::writeWatchVar(const QString &varName, const QString &value)
{
postCommand("-var-assign",QString("%1 %2").arg(varName, value));
}
void GDBMIDebuggerClient::addWatchpoint(const QString &watchExp)
{
if (!watchExp.isEmpty())
postCommand("-break-watch", watchExp, DebugCommandSource::Other);
postCommand("-break-watch", watchExp);
}
void GDBMIDebuggerClient::refreshWatchVar(PWatchVar var)
void GDBMIDebuggerClient::refreshWatch(PWatchVar var)
{
Q_ASSERT(var!=nullptr);
postCommand("-var-update",
QString(" --all-values %1").arg(var->name),
DebugCommandSource::Other);
QString(" --all-values %1").arg(var->name));
}
void GDBMIDebuggerClient::refreshWatch()
{
postCommand("-var-update"," --all-values *");
}
void GDBMIDebuggerClient::fetchWatchVarChildren(const QString& varName)
{
postCommand("-var-list-children", varName);
}
void GDBMIDebuggerClient::evalExpression(const QString &expression)
{
postCommand("-data-evaluate-expression", expression);
}
void GDBMIDebuggerClient::refreshFrame()
{
postCommand("-stack-info-frame", "");
}
void GDBMIDebuggerClient::refreshRegisters()
{
postCommand("-data-list-register-values", "N");
}
void GDBMIDebuggerClient::disassembleCurrentFrame(bool blendMode)
{
if (blendMode)
postCommand("disas", "/s");
else
postCommand("disas", "");
}
void GDBMIDebuggerClient::runInferiorStoppedHook()

View File

@ -38,21 +38,39 @@ using PDebugCommand = std::shared_ptr<DebugCommand>;
class GDBMIDebuggerClient: public DebuggerClient {
Q_OBJECT
public:
explicit GDBMIDebuggerClient(Debugger* debugger, QObject *parent = nullptr);
explicit GDBMIDebuggerClient(Debugger* debugger, DebuggerType clientType, QObject *parent = nullptr);
// DebuggerClient interface
public:
void postCommand(const QString &Command, const QString &Params, DebugCommandSource Source) override;
void postCommand(const QString &Command, const QString &Params, DebugCommandSource Source = DebugCommandSource::Other) override;
void registerInferiorStoppedCommand(const QString &Command, const QString &Params) override;
void stopDebug() override;
DebuggerType clientType() override;
const PDebugCommand &currentCmd() const;
void interrupt() override;
void refreshStackVariables() override;
void readMemory(qulonglong startAddress, int rows, int cols) override;
void setBreakpointCondition(PBreakpoint breakpoint) override;
void writeMemory(qulonglong address, unsigned char data) override;
void addBreakpoint(PBreakpoint breakpoint) override;
void removeBreakpoint(PBreakpoint breakpoint) override;
void addWatchpoint(const QString& watchExp) override;
void refreshWatchVar(PWatchVar var) override;
void setBreakpointCondition(PBreakpoint breakpoint) override;
void addWatch(const QString& expression) override;
void removeWatch(PWatchVar watchVar) override;
void writeWatchVar(const QString& varName, const QString& value) override;
void refreshWatch(PWatchVar var) override;
void refreshWatch() override;
void fetchWatchVarChildren(const QString& varName) override;
void evalExpression(const QString& expression) override;
void refreshFrame();
void refreshRegisters();
void disassembleCurrentFrame(bool blendMode);
// QThread interface
protected:
void run() override;
@ -100,6 +118,7 @@ private:
PDebugCommand mCurrentCmd;
QList<PDebugCommand> mInferiorStoppedHookCommands;
DebuggerType mClientType;
};
#endif // GDBMI_DEBUGGER_H

View File

@ -4108,7 +4108,7 @@ void Editor::showDebugHint(const QString &s, int line)
connect(pMainWindow->debugger(), &Debugger::evalValueReady,
this, &Editor::onTipEvalValueReady);
mCurrentDebugTipWord = s;
pMainWindow->debugger()->sendCommand("-data-evaluate-expression",s);
pMainWindow->debugger()->evalExpression(s);
}
QString Editor::getErrorHint(const PSyntaxIssue& issue)

View File

@ -6501,7 +6501,7 @@ void MainWindow::onDebugEvaluateInput()
if (!s.isEmpty()) {
connect(mDebugger.get(), &Debugger::evalValueReady,
this, &MainWindow::onEvalValueReady);
mDebugger->sendCommand("-data-evaluate-expression",s);
mDebugger->evalExpression(s);
pMainWindow->debugger()->refreshAll();
}
}