DAP Protocol implementations.
More work for seperating debugger interface and the gdb mi client
This commit is contained in:
parent
9a66022b8a
commit
d302fcc10f
|
@ -130,6 +130,7 @@ SOURCES += \
|
||||||
debugger/gdbmidebugger.cpp \
|
debugger/gdbmidebugger.cpp \
|
||||||
debugger/gdbmiresultparser.cpp \
|
debugger/gdbmiresultparser.cpp \
|
||||||
debugger/dapprotocol.cpp \
|
debugger/dapprotocol.cpp \
|
||||||
|
debugger/dapdebugger.cpp \
|
||||||
cpprefacter.cpp \
|
cpprefacter.cpp \
|
||||||
parser/cppparser.cpp \
|
parser/cppparser.cpp \
|
||||||
parser/cpppreprocessor.cpp \
|
parser/cpppreprocessor.cpp \
|
||||||
|
@ -261,6 +262,7 @@ HEADERS += \
|
||||||
debugger/gdbmidebugger.h \
|
debugger/gdbmidebugger.h \
|
||||||
debugger/gdbmiresultparser.h \
|
debugger/gdbmiresultparser.h \
|
||||||
debugger/dapprotocol.h \
|
debugger/dapprotocol.h \
|
||||||
|
debugger/dapdebugger.h \
|
||||||
cpprefacter.h \
|
cpprefacter.h \
|
||||||
customfileiconprovider.h \
|
customfileiconprovider.h \
|
||||||
parser/cppparser.h \
|
parser/cppparser.h \
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
#include "dapdebugger.h"
|
||||||
|
#include "../utils.h"
|
||||||
|
#include "dapprotocol.h"
|
||||||
|
#include "../systemconsts.h"
|
||||||
|
|
||||||
|
#include <QFileInfo>
|
||||||
|
|
||||||
|
DAPDebuggerClient::DAPDebuggerClient(Debugger *debugger, QObject *parent):
|
||||||
|
DebuggerClient{debugger, parent}
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void DAPDebuggerClient::run()
|
||||||
|
{
|
||||||
|
mStop = false;
|
||||||
|
bool errorOccured = false;
|
||||||
|
mInferiorRunning = false;
|
||||||
|
mProcessExited = false;
|
||||||
|
QString cmd = debuggerPath();
|
||||||
|
// QString arguments = "--annotate=2";
|
||||||
|
QStringList arguments{"--interpret=mi", "--silent"};
|
||||||
|
QString workingDir = QFileInfo(debuggerPath()).path();
|
||||||
|
|
||||||
|
mProcess = std::make_shared<QProcess>();
|
||||||
|
auto action = finally([&]{
|
||||||
|
mProcess.reset();
|
||||||
|
});
|
||||||
|
mProcess->setProgram(cmd);
|
||||||
|
mProcess->setArguments(arguments);
|
||||||
|
|
||||||
|
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
||||||
|
QString path = env.value("PATH");
|
||||||
|
QStringList pathAdded = binDirs();
|
||||||
|
if (!path.isEmpty()) {
|
||||||
|
path = pathAdded.join(PATH_SEPARATOR) + PATH_SEPARATOR + path;
|
||||||
|
} else {
|
||||||
|
path = pathAdded.join(PATH_SEPARATOR);
|
||||||
|
}
|
||||||
|
QString cmdDir = extractFileDir(cmd);
|
||||||
|
if (!cmdDir.isEmpty()) {
|
||||||
|
path = cmdDir + PATH_SEPARATOR + path;
|
||||||
|
}
|
||||||
|
env.insert("PATH",path);
|
||||||
|
mProcess->setProcessEnvironment(env);
|
||||||
|
|
||||||
|
mProcess->setWorkingDirectory(workingDir);
|
||||||
|
|
||||||
|
connect(mProcess.get(), &QProcess::errorOccurred,
|
||||||
|
[&](){
|
||||||
|
errorOccured= true;
|
||||||
|
});
|
||||||
|
QByteArray buffer;
|
||||||
|
QByteArray readed;
|
||||||
|
|
||||||
|
mProcess->start();
|
||||||
|
mProcess->waitForStarted(5000);
|
||||||
|
mStartSemaphore.release(1);
|
||||||
|
while (true) {
|
||||||
|
mProcess->waitForFinished(1);
|
||||||
|
if (mProcess->state()!=QProcess::Running) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (mStop) {
|
||||||
|
mProcess->terminate();
|
||||||
|
mProcess->kill();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (errorOccured)
|
||||||
|
break;
|
||||||
|
readed = mProcess->readAll();
|
||||||
|
buffer += readed;
|
||||||
|
|
||||||
|
if (readed.endsWith("\n")&& outputTerminated(buffer)) {
|
||||||
|
processDebugOutput(buffer);
|
||||||
|
buffer.clear();
|
||||||
|
mCmdRunning = false;
|
||||||
|
runNextCmd();
|
||||||
|
} else if (!mCmdRunning && readed.isEmpty()){
|
||||||
|
runNextCmd();
|
||||||
|
} else if (readed.isEmpty()){
|
||||||
|
msleep(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (errorOccured) {
|
||||||
|
emit processFailed(mProcess->error());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com)
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef DAP_DEBUGGER_H
|
||||||
|
#define DAP_DEBUGGER_H
|
||||||
|
|
||||||
|
#include "debugger.h"
|
||||||
|
|
||||||
|
class DAPDebuggerClient : public DebuggerClient {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit DAPDebuggerClient(Debugger* debugger, QObject *parent = nullptr);
|
||||||
|
|
||||||
|
|
||||||
|
// QThread interface
|
||||||
|
protected:
|
||||||
|
void run() override;
|
||||||
|
|
||||||
|
// DebuggerClient interface
|
||||||
|
public:
|
||||||
|
void postCommand(const QString &Command, const QString &Params, DebugCommandSource Source) override;
|
||||||
|
void registerInferiorStoppedCommand(const QString &Command, const QString &Params) override;
|
||||||
|
void stopDebug() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void runNextCmd() override;
|
||||||
|
private:
|
||||||
|
void initializeRequest();
|
||||||
|
private:
|
||||||
|
std::shared_ptr<QProcess> mProcess;
|
||||||
|
bool mStop;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -57,6 +57,9 @@ QString createDAPResponseMessage(
|
||||||
qint64 seq, qint64 request_seq, bool success,
|
qint64 seq, qint64 request_seq, bool success,
|
||||||
const QString& command, const QString& message, const QJsonObject& body);
|
const QString& command, const QString& message, const QJsonObject& body);
|
||||||
|
|
||||||
|
QString createDAPEventMessage(
|
||||||
|
qint64 seq, const QString& event, const QJsonObject& body);
|
||||||
|
|
||||||
std::shared_ptr<DAPProtocolMessage> parseDAPMessage(const QByteArray& contentPart);
|
std::shared_ptr<DAPProtocolMessage> parseDAPMessage(const QByteArray& contentPart);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -270,12 +270,14 @@ void Debugger::updateRegisterValues(const QHash<int, QString> &values)
|
||||||
void Debugger::refreshAll()
|
void Debugger::refreshAll()
|
||||||
{
|
{
|
||||||
refreshWatchVars();
|
refreshWatchVars();
|
||||||
sendCommand("-stack-list-variables", "--all-values");
|
if (mExecuting && mClient)
|
||||||
if (memoryModel()->startAddress()>0)
|
mClient->refreshStackVariables();
|
||||||
sendCommand("-data-read-memory",QString("%1 x 1 %2 %3 ")
|
if (memoryModel()->startAddress()>0
|
||||||
.arg(memoryModel()->startAddress())
|
&& mExecuting && mClient)
|
||||||
.arg(pSettings->debugger().memoryViewRows())
|
mClient->readMemory(
|
||||||
.arg(pSettings->debugger().memoryViewColumns())
|
memoryModel()->startAddress(),
|
||||||
|
pSettings->debugger().memoryViewRows(),
|
||||||
|
pSettings->debugger().memoryViewColumns()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,7 +316,9 @@ bool Debugger::inferiorRunning()
|
||||||
|
|
||||||
void Debugger::interrupt()
|
void Debugger::interrupt()
|
||||||
{
|
{
|
||||||
sendCommand("-exec-interrupt", "");
|
if (mExecuting && mClient) {
|
||||||
|
mClient->interrupt();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Debugger::isForProject() const
|
bool Debugger::isForProject() const
|
||||||
|
@ -437,13 +441,8 @@ 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 (condition.isEmpty()) {
|
if (mExecuting && mClient)
|
||||||
sendCommand("-break-condition",
|
mClient->setBreakpointCondition(breakpoint);
|
||||||
QString("%1").arg(breakpoint->number));
|
|
||||||
} else {
|
|
||||||
sendCommand("-break-condition",
|
|
||||||
QString("%1 %2").arg(breakpoint->number).arg(condition));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Debugger::sendAllBreakpointsToDebugger()
|
void Debugger::sendAllBreakpointsToDebugger()
|
||||||
|
@ -495,8 +494,8 @@ 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 (!s.isEmpty()) {
|
if (mExecuting && mClient) {
|
||||||
sendCommand("-break-watch",s,DebugCommandSource::Other);
|
mClient->addWatchpoint(expression);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -545,12 +544,12 @@ void Debugger::modifyWatchVarExpression(const QString &oldExpr, const QString &n
|
||||||
|
|
||||||
void Debugger::refreshWatchVars()
|
void Debugger::refreshWatchVars()
|
||||||
{
|
{
|
||||||
if (mExecuting) {
|
if (mExecuting && 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())
|
||||||
sendCommand("-var-update",QString(" --all-values %1").arg(var->name));
|
mClient->refreshWatchVar(var);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sendCommand("-var-update"," --all-values *");
|
sendCommand("-var-update"," --all-values *");
|
||||||
|
@ -1003,23 +1002,6 @@ DebuggerClient::DebuggerClient(Debugger* debugger, QObject *parent) : QThread(pa
|
||||||
mCmdRunning = false;
|
mCmdRunning = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerClient::clearCmdQueue()
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&mCmdQueueMutex);
|
|
||||||
mCmdQueue.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebuggerClient::runInferiorStoppedHook()
|
|
||||||
{
|
|
||||||
QMutexLocker locker(&mCmdQueueMutex);
|
|
||||||
foreach (const PDebugCommand& cmd, mInferiorStoppedHookCommands) {
|
|
||||||
mCmdQueue.push_front(cmd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const QStringList &DebuggerClient::binDirs() const
|
const QStringList &DebuggerClient::binDirs() const
|
||||||
{
|
{
|
||||||
return mBinDirs;
|
return mBinDirs;
|
||||||
|
@ -1065,11 +1047,6 @@ bool DebuggerClient::updateCPUInfo() const
|
||||||
return mUpdateCPUInfo;
|
return mUpdateCPUInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PDebugCommand &DebuggerClient::currentCmd() const
|
|
||||||
{
|
|
||||||
return mCurrentCmd;
|
|
||||||
}
|
|
||||||
|
|
||||||
const QStringList &DebuggerClient::consoleOutput() const
|
const QStringList &DebuggerClient::consoleOutput() const
|
||||||
{
|
{
|
||||||
return mConsoleOutput;
|
return mConsoleOutput;
|
||||||
|
|
|
@ -45,13 +45,6 @@ enum class DebuggerType {
|
||||||
DAP
|
DAP
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DebugCommand{
|
|
||||||
QString command;
|
|
||||||
QString params;
|
|
||||||
DebugCommandSource source;
|
|
||||||
};
|
|
||||||
|
|
||||||
using PDebugCommand = std::shared_ptr<DebugCommand>;
|
|
||||||
struct WatchVar;
|
struct WatchVar;
|
||||||
using PWatchVar = std::shared_ptr<WatchVar>;
|
using PWatchVar = std::shared_ptr<WatchVar>;
|
||||||
struct WatchVar {
|
struct WatchVar {
|
||||||
|
@ -482,8 +475,6 @@ public:
|
||||||
|
|
||||||
const QStringList &consoleOutput() const;
|
const QStringList &consoleOutput() const;
|
||||||
|
|
||||||
const PDebugCommand ¤tCmd() const;
|
|
||||||
|
|
||||||
bool updateCPUInfo() const;
|
bool updateCPUInfo() const;
|
||||||
|
|
||||||
bool receivedSFWarning() const;
|
bool receivedSFWarning() const;
|
||||||
|
@ -501,6 +492,15 @@ public:
|
||||||
void addBinDir(const QString &binDir);
|
void addBinDir(const QString &binDir);
|
||||||
|
|
||||||
Debugger* debugger() { return mDebugger; }
|
Debugger* debugger() { return mDebugger; }
|
||||||
|
|
||||||
|
//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 addWatchpoint(const QString& watchExp) = 0;
|
||||||
|
virtual void refreshWatchVar(PWatchVar var) = 0;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void parseStarted();
|
void parseStarted();
|
||||||
void invalidateAllVars();
|
void invalidateAllVars();
|
||||||
|
@ -540,21 +540,18 @@ signals:
|
||||||
void varsValueUpdated();
|
void varsValueUpdated();
|
||||||
protected:
|
protected:
|
||||||
virtual void runNextCmd() = 0;
|
virtual void runNextCmd() = 0;
|
||||||
void clearCmdQueue();
|
|
||||||
void runInferiorStoppedHook();
|
|
||||||
protected:
|
protected:
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
||||||
QRecursiveMutex mCmdQueueMutex;
|
QRecursiveMutex mCmdQueueMutex;
|
||||||
#else
|
#else
|
||||||
QMutex mCmdQueueMutex;
|
QMutex mCmdQueueMutex;
|
||||||
#endif
|
#endif
|
||||||
QQueue<PDebugCommand> mCmdQueue;
|
|
||||||
bool mCmdRunning;
|
bool mCmdRunning;
|
||||||
|
|
||||||
QList<PDebugCommand> mInferiorStoppedHookCommands;
|
|
||||||
bool mInferiorRunning;
|
bool mInferiorRunning;
|
||||||
bool mProcessExited;
|
bool mProcessExited;
|
||||||
PDebugCommand mCurrentCmd;
|
|
||||||
QStringList mConsoleOutput;
|
QStringList mConsoleOutput;
|
||||||
QStringList mFullOutput;
|
QStringList mFullOutput;
|
||||||
QSemaphore mStartSemaphore;
|
QSemaphore mStartSemaphore;
|
||||||
|
|
|
@ -860,4 +860,65 @@ void GDBMIDebuggerClient::asyncUpdate()
|
||||||
mAsyncUpdated = false;
|
mAsyncUpdated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PDebugCommand &GDBMIDebuggerClient::currentCmd() const
|
||||||
|
{
|
||||||
|
return mCurrentCmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GDBMIDebuggerClient::interrupt()
|
||||||
|
{
|
||||||
|
postCommand("-exec-interrupt", "", DebugCommandSource::Other);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GDBMIDebuggerClient::refreshStackVariables()
|
||||||
|
{
|
||||||
|
postCommand("-stack-list-variables", "--all-values", DebugCommandSource::Other);
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GDBMIDebuggerClient::setBreakpointCondition(PBreakpoint breakpoint)
|
||||||
|
{
|
||||||
|
Q_ASSERT(breakpoint!=nullptr);
|
||||||
|
QString condition = breakpoint->condition;
|
||||||
|
if (condition.isEmpty()) {
|
||||||
|
postCommand("-break-condition",
|
||||||
|
QString("%1").arg(breakpoint->number), DebugCommandSource::Other);
|
||||||
|
} else {
|
||||||
|
postCommand("-break-condition",
|
||||||
|
QString("%1 %2").arg(breakpoint->number).arg(condition), DebugCommandSource::Other);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GDBMIDebuggerClient::addWatchpoint(const QString &watchExp)
|
||||||
|
{
|
||||||
|
if (!watchExp.isEmpty())
|
||||||
|
postCommand("-break-watch", watchExp, DebugCommandSource::Other);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GDBMIDebuggerClient::refreshWatchVar(PWatchVar var)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void GDBMIDebuggerClient::runInferiorStoppedHook()
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&mCmdQueueMutex);
|
||||||
|
foreach (const PDebugCommand& cmd, mInferiorStoppedHookCommands) {
|
||||||
|
mCmdQueue.push_front(cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GDBMIDebuggerClient::clearCmdQueue()
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&mCmdQueueMutex);
|
||||||
|
mCmdQueue.clear();
|
||||||
|
}
|
||||||
|
|
|
@ -27,6 +27,14 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
|
||||||
|
struct DebugCommand{
|
||||||
|
QString command;
|
||||||
|
QString params;
|
||||||
|
DebugCommandSource source;
|
||||||
|
};
|
||||||
|
|
||||||
|
using PDebugCommand = std::shared_ptr<DebugCommand>;
|
||||||
|
|
||||||
class GDBMIDebuggerClient: public DebuggerClient {
|
class GDBMIDebuggerClient: public DebuggerClient {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
@ -37,6 +45,14 @@ 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;
|
||||||
|
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 addWatchpoint(const QString& watchExp) override;
|
||||||
|
void refreshWatchVar(PWatchVar var) override;
|
||||||
// QThread interface
|
// QThread interface
|
||||||
protected:
|
protected:
|
||||||
void run() override;
|
void run() override;
|
||||||
|
@ -63,6 +79,8 @@ private:
|
||||||
void processResultRecord(const QByteArray& line);
|
void processResultRecord(const QByteArray& line);
|
||||||
void processDebugOutput(const QByteArray& debugOutput);
|
void processDebugOutput(const QByteArray& debugOutput);
|
||||||
QByteArray removeToken(const QByteArray& line) const;
|
QByteArray removeToken(const QByteArray& line) const;
|
||||||
|
void runInferiorStoppedHook();
|
||||||
|
void clearCmdQueue();
|
||||||
private slots:
|
private slots:
|
||||||
void asyncUpdate();
|
void asyncUpdate();
|
||||||
private:
|
private:
|
||||||
|
@ -77,6 +95,11 @@ private:
|
||||||
bool mAsyncUpdated;
|
bool mAsyncUpdated;
|
||||||
|
|
||||||
static const QRegularExpression REGdbSourceLine;
|
static const QRegularExpression REGdbSourceLine;
|
||||||
|
|
||||||
|
QQueue<PDebugCommand> mCmdQueue;
|
||||||
|
PDebugCommand mCurrentCmd;
|
||||||
|
QList<PDebugCommand> mInferiorStoppedHookCommands;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // GDBMI_DEBUGGER_H
|
#endif // GDBMI_DEBUGGER_H
|
||||||
|
|
Loading…
Reference in New Issue