work save
This commit is contained in:
parent
1f8fa070c8
commit
6ba9cbb78b
|
@ -86,3 +86,8 @@ void DAPDebuggerClient::run()
|
|||
emit processFailed(mProcess->error());
|
||||
}
|
||||
}
|
||||
|
||||
DebuggerType DAPDebuggerClient::clientType()
|
||||
{
|
||||
return DebuggerType::DAP;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ¶ms, 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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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 ¤tCmd() 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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue