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()); 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 postCommand(const QString &Command, const QString &Params, DebugCommandSource Source) override;
void registerInferiorStoppedCommand(const QString &Command, const QString &Params) override; void registerInferiorStoppedCommand(const QString &Command, const QString &Params) override;
void stopDebug() override; void stopDebug() override;
DebuggerType clientType() override;
protected: protected:
void runNextCmd() override; void runNextCmd() override;

View File

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

View File

@ -303,8 +303,6 @@ public:
~Debugger(); ~Debugger();
// Play/pause // Play/pause
bool start(int compilerSetIndex, const QString& inferior, const QStringList& binDirs, const QString& sourceFile=QString()); 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 commandRunning();
bool inferiorRunning(); bool inferiorRunning();
void interrupt(); void interrupt();
@ -345,6 +343,10 @@ public:
PWatchVar findWatchVar(const QString& expression); PWatchVar findWatchVar(const QString& expression);
PWatchVar watchVarAt(const QModelIndex& index); PWatchVar watchVarAt(const QModelIndex& index);
void refreshVars(); void refreshVars();
void evalExpression(const QString& expression);
// void notifyWatchVarUpdated(PWatchVar var); // void notifyWatchVarUpdated(PWatchVar var);
std::shared_ptr<BacktraceModel> backtraceModel(); std::shared_ptr<BacktraceModel> backtraceModel();
@ -493,13 +495,33 @@ public:
Debugger* debugger() { return mDebugger; } Debugger* debugger() { return mDebugger; }
virtual DebuggerType clientType() = 0;
//requests //requests
virtual void interrupt() = 0; virtual void interrupt() = 0;
virtual void refreshStackVariables() = 0; virtual void refreshStackVariables() = 0;
virtual void readMemory(qulonglong startAddress, int rows, int cols) = 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 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: signals:
void parseStarted(); void parseStarted();

View File

@ -26,8 +26,12 @@
const QRegularExpression GDBMIDebuggerClient::REGdbSourceLine("^(\\d)+\\s+in\\s+(.+)$"); const QRegularExpression GDBMIDebuggerClient::REGdbSourceLine("^(\\d)+\\s+in\\s+(.+)$");
GDBMIDebuggerClient::GDBMIDebuggerClient(Debugger *debugger, QObject *parent): GDBMIDebuggerClient::GDBMIDebuggerClient(
DebuggerClient(debugger, parent) Debugger *debugger,
DebuggerType clientType,
QObject *parent):
DebuggerClient{debugger, parent},
mClientType{clientType}
{ {
mProcess = std::make_shared<QProcess>(); mProcess = std::make_shared<QProcess>();
mAsyncUpdated = false; mAsyncUpdated = false;
@ -61,6 +65,11 @@ void GDBMIDebuggerClient::stopDebug()
mStop = true; mStop = true;
} }
DebuggerType GDBMIDebuggerClient::clientType()
{
return mClientType;
}
void GDBMIDebuggerClient::run() void GDBMIDebuggerClient::run()
{ {
mStop = false; mStop = false;
@ -867,12 +876,12 @@ const PDebugCommand &GDBMIDebuggerClient::currentCmd() const
void GDBMIDebuggerClient::interrupt() void GDBMIDebuggerClient::interrupt()
{ {
postCommand("-exec-interrupt", "", DebugCommandSource::Other); postCommand("-exec-interrupt", "");
} }
void GDBMIDebuggerClient::refreshStackVariables() 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) 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 ") postCommand("-data-read-memory",QString("%1 x 1 %2 %3 ")
.arg(startAddress) .arg(startAddress)
.arg(rows) .arg(rows)
.arg(cols), .arg(cols));
DebugCommandSource::Other }
);
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) void GDBMIDebuggerClient::setBreakpointCondition(PBreakpoint breakpoint)
@ -891,25 +938,72 @@ void GDBMIDebuggerClient::setBreakpointCondition(PBreakpoint breakpoint)
QString condition = breakpoint->condition; QString condition = breakpoint->condition;
if (condition.isEmpty()) { if (condition.isEmpty()) {
postCommand("-break-condition", postCommand("-break-condition",
QString("%1").arg(breakpoint->number), DebugCommandSource::Other); QString("%1").arg(breakpoint->number));
} else { } else {
postCommand("-break-condition", 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) void GDBMIDebuggerClient::addWatchpoint(const QString &watchExp)
{ {
if (!watchExp.isEmpty()) 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); Q_ASSERT(var!=nullptr);
postCommand("-var-update", postCommand("-var-update",
QString(" --all-values %1").arg(var->name), QString(" --all-values %1").arg(var->name));
DebugCommandSource::Other); }
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() void GDBMIDebuggerClient::runInferiorStoppedHook()

View File

@ -38,21 +38,39 @@ using PDebugCommand = std::shared_ptr<DebugCommand>;
class GDBMIDebuggerClient: public DebuggerClient { class GDBMIDebuggerClient: public DebuggerClient {
Q_OBJECT Q_OBJECT
public: public:
explicit GDBMIDebuggerClient(Debugger* debugger, QObject *parent = nullptr); explicit GDBMIDebuggerClient(Debugger* debugger, DebuggerType clientType, QObject *parent = nullptr);
// DebuggerClient interface // DebuggerClient interface
public: 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 registerInferiorStoppedCommand(const QString &Command, const QString &Params) override;
void stopDebug() override; void stopDebug() override;
DebuggerType clientType() override;
const PDebugCommand &currentCmd() const; const PDebugCommand &currentCmd() const;
void interrupt() override; void interrupt() override;
void refreshStackVariables() override; void refreshStackVariables() override;
void readMemory(qulonglong startAddress, int rows, int cols) 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 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 // QThread interface
protected: protected:
void run() override; void run() override;
@ -100,6 +118,7 @@ private:
PDebugCommand mCurrentCmd; PDebugCommand mCurrentCmd;
QList<PDebugCommand> mInferiorStoppedHookCommands; QList<PDebugCommand> mInferiorStoppedHookCommands;
DebuggerType mClientType;
}; };
#endif // GDBMI_DEBUGGER_H #endif // GDBMI_DEBUGGER_H

View File

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

View File

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