work save: refactor: DebuggerClient interface

This commit is contained in:
Roy Qu 2024-03-08 22:06:10 +08:00
parent 4567e11f43
commit 581b7c7cf1
14 changed files with 302 additions and 253 deletions

View File

@ -121,12 +121,14 @@ SOURCES += \
compiler/projectcompiler.cpp \ compiler/projectcompiler.cpp \
compiler/runner.cpp \ compiler/runner.cpp \
customfileiconprovider.cpp \ customfileiconprovider.cpp \
gdbmiresultparser.cpp \
compiler/compiler.cpp \ compiler/compiler.cpp \
compiler/compilermanager.cpp \ compiler/compilermanager.cpp \
compiler/executablerunner.cpp \ compiler/executablerunner.cpp \
compiler/filecompiler.cpp \ compiler/filecompiler.cpp \
compiler/stdincompiler.cpp \ compiler/stdincompiler.cpp \
debugger/debugger.cpp \
debugger/gdbmidebugger.cpp \
debugger/gdbmiresultparser.cpp \
cpprefacter.cpp \ cpprefacter.cpp \
parser/cppparser.cpp \ parser/cppparser.cpp \
parser/cpppreprocessor.cpp \ parser/cpppreprocessor.cpp \
@ -179,7 +181,6 @@ SOURCES += \
widgets/codecompletionlistview.cpp \ widgets/codecompletionlistview.cpp \
widgets/codecompletionpopup.cpp \ widgets/codecompletionpopup.cpp \
widgets/cpudialog.cpp \ widgets/cpudialog.cpp \
debugger/debugger.cpp \
editor.cpp \ editor.cpp \
editorlist.cpp \ editorlist.cpp \
iconsmanager.cpp \ iconsmanager.cpp \
@ -255,9 +256,11 @@ HEADERS += \
compiler/projectcompiler.h \ compiler/projectcompiler.h \
compiler/runner.h \ compiler/runner.h \
compiler/stdincompiler.h \ compiler/stdincompiler.h \
debugger/debugger.h \
debugger/gdbmidebugger.h \
debugger/gdbmiresultparser.h \
cpprefacter.h \ cpprefacter.h \
customfileiconprovider.h \ customfileiconprovider.h \
gdbmiresultparser.h \
parser/cppparser.h \ parser/cppparser.h \
parser/cpppreprocessor.h \ parser/cpppreprocessor.h \
parser/cpptokenizer.h \ parser/cpptokenizer.h \
@ -309,7 +312,6 @@ HEADERS += \
widgets/codecompletionlistview.h \ widgets/codecompletionlistview.h \
widgets/codecompletionpopup.h \ widgets/codecompletionpopup.h \
widgets/cpudialog.h \ widgets/cpudialog.h \
debugger/debugger.h \
editor.h \ editor.h \
editorlist.h \ editorlist.h \
iconsmanager.h \ iconsmanager.h \

View File

@ -52,7 +52,7 @@ Debugger::Debugger(QObject *parent) : QObject(parent),
connect(mWatchModel.get(), &WatchModel::setWatchVarValue, connect(mWatchModel.get(), &WatchModel::setWatchVarValue,
this, &Debugger::setWatchVarValue); this, &Debugger::setWatchVarValue);
mExecuting = false; mExecuting = false;
mReader = nullptr; mClient = nullptr;
mTarget = nullptr; mTarget = nullptr;
mCommandChanged = false; mCommandChanged = false;
mLeftPageIndexBackup = -1; mLeftPageIndexBackup = -1;
@ -158,56 +158,56 @@ bool Debugger::start(int compilerSetIndex, const QString& inferior, const QStrin
mTarget->waitStart(); mTarget->waitStart();
} }
//delete when thread finished //delete when thread finished
mReader = new DebugReader(this); mClient = new DebuggerClient(this);
mReader->addBinDirs(binDirs); mClient->addBinDirs(binDirs);
mReader->addBinDir(pSettings->dirs().appDir()); mClient->addBinDir(pSettings->dirs().appDir());
mReader->setDebuggerPath(debuggerPath); mClient->setDebuggerPath(debuggerPath);
connect(mReader, &QThread::finished,this,&Debugger::cleanUpReader); connect(mClient, &QThread::finished,this,&Debugger::cleanUpReader);
connect(mReader, &QThread::finished,mMemoryModel.get(),&MemoryModel::reset); connect(mClient, &QThread::finished,mMemoryModel.get(),&MemoryModel::reset);
connect(mReader, &DebugReader::parseFinished,this,&Debugger::syncFinishedParsing,Qt::BlockingQueuedConnection); connect(mClient, &DebuggerClient::parseFinished,this,&Debugger::syncFinishedParsing,Qt::BlockingQueuedConnection);
connect(mReader, &DebugReader::changeDebugConsoleLastLine,this,&Debugger::onChangeDebugConsoleLastline); connect(mClient, &DebuggerClient::changeDebugConsoleLastLine,this,&Debugger::onChangeDebugConsoleLastline);
connect(mReader, &DebugReader::cmdStarted,pMainWindow, &MainWindow::disableDebugActions); connect(mClient, &DebuggerClient::cmdStarted,pMainWindow, &MainWindow::disableDebugActions);
connect(mReader, &DebugReader::cmdFinished,pMainWindow, &MainWindow::enableDebugActions); connect(mClient, &DebuggerClient::cmdFinished,pMainWindow, &MainWindow::enableDebugActions);
connect(mReader, &DebugReader::inferiorStopped, pMainWindow, &MainWindow::enableDebugActions); connect(mClient, &DebuggerClient::inferiorStopped, pMainWindow, &MainWindow::enableDebugActions);
connect(mReader, &DebugReader::breakpointInfoGetted, mBreakpointModel.get(), connect(mClient, &DebuggerClient::breakpointInfoGetted, mBreakpointModel.get(),
&BreakpointModel::updateBreakpointNumber); &BreakpointModel::updateBreakpointNumber);
connect(mReader, &DebugReader::localsUpdated, pMainWindow, connect(mClient, &DebuggerClient::localsUpdated, pMainWindow,
&MainWindow::onLocalsReady); &MainWindow::onLocalsReady);
connect(mReader, &DebugReader::memoryUpdated,this, connect(mClient, &DebuggerClient::memoryUpdated,this,
&Debugger::updateMemory); &Debugger::updateMemory);
connect(mReader, &DebugReader::evalUpdated,this, connect(mClient, &DebuggerClient::evalUpdated,this,
&Debugger::updateEval); &Debugger::updateEval);
connect(mReader, &DebugReader::disassemblyUpdate,this, connect(mClient, &DebuggerClient::disassemblyUpdate,this,
&Debugger::updateDisassembly); &Debugger::updateDisassembly);
connect(mReader, &DebugReader::registerNamesUpdated, this, connect(mClient, &DebuggerClient::registerNamesUpdated, this,
&Debugger::updateRegisterNames); &Debugger::updateRegisterNames);
connect(mReader, &DebugReader::registerValuesUpdated, this, connect(mClient, &DebuggerClient::registerValuesUpdated, this,
&Debugger::updateRegisterValues); &Debugger::updateRegisterValues);
connect(mReader, &DebugReader::varCreated,mWatchModel.get(), connect(mClient, &DebuggerClient::varCreated,mWatchModel.get(),
&WatchModel::updateVarInfo); &WatchModel::updateVarInfo);
connect(mReader, &DebugReader::prepareVarChildren,mWatchModel.get(), connect(mClient, &DebuggerClient::prepareVarChildren,mWatchModel.get(),
&WatchModel::prepareVarChildren); &WatchModel::prepareVarChildren);
connect(mReader, &DebugReader::addVarChild,mWatchModel.get(), connect(mClient, &DebuggerClient::addVarChild,mWatchModel.get(),
&WatchModel::addVarChild); &WatchModel::addVarChild);
connect(mReader, &DebugReader::varValueUpdated,mWatchModel.get(), connect(mClient, &DebuggerClient::varValueUpdated,mWatchModel.get(),
&WatchModel::updateVarValue); &WatchModel::updateVarValue);
connect(mReader, &DebugReader::varsValueUpdated,mWatchModel.get(), connect(mClient, &DebuggerClient::varsValueUpdated,mWatchModel.get(),
&WatchModel::updateAllHasMoreVars); &WatchModel::updateAllHasMoreVars);
connect(mReader, &DebugReader::inferiorContinued,pMainWindow, connect(mClient, &DebuggerClient::inferiorContinued,pMainWindow,
&MainWindow::removeActiveBreakpoints); &MainWindow::removeActiveBreakpoints);
connect(mReader, &DebugReader::inferiorStopped,pMainWindow, connect(mClient, &DebuggerClient::inferiorStopped,pMainWindow,
&MainWindow::setActiveBreakpoint); &MainWindow::setActiveBreakpoint);
connect(mReader, &DebugReader::watchpointHitted,pMainWindow, connect(mClient, &DebuggerClient::watchpointHitted,pMainWindow,
&MainWindow::onWatchpointHitted); &MainWindow::onWatchpointHitted);
connect(mReader, &DebugReader::errorNoSymbolTable,pMainWindow, connect(mClient, &DebuggerClient::errorNoSymbolTable,pMainWindow,
&MainWindow::stopDebugForNoSymbolTable); &MainWindow::stopDebugForNoSymbolTable);
connect(mReader, &DebugReader::inferiorStopped,this, connect(mClient, &DebuggerClient::inferiorStopped,this,
&Debugger::refreshAll); &Debugger::refreshAll);
mReader->registerInferiorStoppedCommand("-stack-list-frames",""); mClient->registerInferiorStoppedCommand("-stack-list-frames","");
mReader->start(); mClient->start();
mReader->waitStart(); mClient->waitStart();
pMainWindow->updateAppTitle(); pMainWindow->updateAppTitle();
@ -220,7 +220,7 @@ void Debugger::stop() {
mTarget->stopDebug(); mTarget->stopDebug();
mTarget = nullptr; mTarget = nullptr;
} }
mReader->stopDebug(); mClient->stopDebug();
} }
mCurrentSourceFile=""; mCurrentSourceFile="";
} }
@ -230,8 +230,8 @@ void Debugger::cleanUpReader()
mExecuting = false; mExecuting = false;
//stop debugger //stop debugger
mReader->deleteLater(); mClient->deleteLater();
mReader=nullptr; mClient=nullptr;
if (pMainWindow->cpuDialog()!=nullptr) { if (pMainWindow->cpuDialog()!=nullptr) {
pMainWindow->cpuDialog()->close(); pMainWindow->cpuDialog()->close();
@ -290,23 +290,23 @@ std::shared_ptr<WatchModel> Debugger::watchModel() const
void Debugger::sendCommand(const QString &command, const QString &params, DebugCommandSource source) void Debugger::sendCommand(const QString &command, const QString &params, DebugCommandSource source)
{ {
if (mExecuting && mReader) { if (mExecuting && mClient) {
mReader->postCommand(command,params,source); mClient->postCommand(command,params,source);
} }
} }
bool Debugger::commandRunning() bool Debugger::commandRunning()
{ {
if (mExecuting && mReader) { if (mExecuting && mClient) {
return mReader->commandRunning(); return mClient->commandRunning();
} }
return false; return false;
} }
bool Debugger::inferiorRunning() bool Debugger::inferiorRunning()
{ {
if (mExecuting && mReader) { if (mExecuting && mClient) {
return mReader->inferiorRunning(); return mClient->inferiorRunning();
} }
return false; return false;
} }
@ -876,7 +876,7 @@ void Debugger::syncFinishedParsing()
bool spawnedcpuform = false; bool spawnedcpuform = false;
// GDB determined that the source code is more recent than the executable. Ask the user if he wants to rebuild. // GDB determined that the source code is more recent than the executable. Ask the user if he wants to rebuild.
if (mReader->receivedSFWarning()) { if (mClient->receivedSFWarning()) {
if (QMessageBox::question(pMainWindow, if (QMessageBox::question(pMainWindow,
tr("Compile"), tr("Compile"),
tr("Source file is more recent than executable.")+"<BR /><BR />" + tr("Recompile?"), tr("Source file is more recent than executable.")+"<BR /><BR />" + tr("Recompile?"),
@ -892,20 +892,20 @@ void Debugger::syncFinishedParsing()
// show command output // show command output
if (pSettings->debugger().enableDebugConsole() ) { if (pSettings->debugger().enableDebugConsole() ) {
if (pSettings->debugger().showDetailLog()) { if (pSettings->debugger().showDetailLog()) {
for (const QString& line:mReader->fullOutput()) { for (const QString& line:mClient->fullOutput()) {
pMainWindow->addDebugOutput(line); pMainWindow->addDebugOutput(line);
} }
} else { } else {
if (mReader->currentCmd() && mReader->currentCmd()->command == "disas") { if (mClient->currentCmd() && mClient->currentCmd()->command == "disas") {
} else { } else {
for (const QString& line:mReader->consoleOutput()) { for (const QString& line:mClient->consoleOutput()) {
pMainWindow->addDebugOutput(line); pMainWindow->addDebugOutput(line);
} }
if ( if (
(mReader->currentCmd() (mClient->currentCmd()
&& mReader->currentCmd()->source== DebugCommandSource::Console) && mClient->currentCmd()->source== DebugCommandSource::Console)
|| !mReader->consoleOutput().isEmpty() ) { || !mClient->consoleOutput().isEmpty() ) {
pMainWindow->addDebugOutput("(gdb)"); pMainWindow->addDebugOutput("(gdb)");
} }
} }
@ -913,20 +913,20 @@ void Debugger::syncFinishedParsing()
} }
// The program to debug has stopped. Stop the debugger // The program to debug has stopped. Stop the debugger
if (mReader->processExited()) { if (mClient->processExited()) {
stop(); stop();
return; return;
} }
if (mReader->signalReceived() if (mClient->signalReceived()
&& mReader->signalName()!="SIGINT" && mClient->signalName()!="SIGINT"
&& mReader->signalName()!="SIGTRAP") { && mClient->signalName()!="SIGTRAP") {
SignalMessageDialog dialog(pMainWindow); SignalMessageDialog dialog(pMainWindow);
dialog.setOpenCPUInfo(pSettings->debugger().openCPUInfoWhenSignaled()); dialog.setOpenCPUInfo(pSettings->debugger().openCPUInfoWhenSignaled());
dialog.setMessage( dialog.setMessage(
tr("Signal \"%1\" Received: ").arg(mReader->signalName()) tr("Signal \"%1\" Received: ").arg(mClient->signalName())
+ "<br />" + "<br />"
+ mReader->signalMeaning()); + mClient->signalMeaning());
int result = dialog.exec(); int result = dialog.exec();
if (result == QDialog::Accepted && dialog.openCPUInfo()) { if (result == QDialog::Accepted && dialog.openCPUInfo()) {
pMainWindow->showCPUInfoDialog(); pMainWindow->showCPUInfoDialog();
@ -934,7 +934,7 @@ void Debugger::syncFinishedParsing()
} }
// CPU form updates itself when spawned, don't update twice! // CPU form updates itself when spawned, don't update twice!
if ((mReader->updateCPUInfo() && !spawnedcpuform) && (pMainWindow->cpuDialog()!=nullptr)) { if ((mClient->updateCPUInfo() && !spawnedcpuform) && (pMainWindow->cpuDialog()!=nullptr)) {
pMainWindow->cpuDialog()->updateInfo(); pMainWindow->cpuDialog()->updateInfo();
} }
} }
@ -990,7 +990,7 @@ bool Debugger::executing() const
return mExecuting; return mExecuting;
} }
DebugReader::DebugReader(Debugger* debugger, QObject *parent) : QThread(parent), DebuggerClient::DebuggerClient(Debugger* debugger, QObject *parent) : QThread(parent),
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
mCmdQueueMutex(), mCmdQueueMutex(),
#else #else
@ -1004,36 +1004,13 @@ DebugReader::DebugReader(Debugger* debugger, QObject *parent) : QThread(parent),
mAsyncUpdated = false; mAsyncUpdated = false;
} }
void DebugReader::postCommand(const QString &Command, const QString &Params, void DebuggerClient::clearCmdQueue()
DebugCommandSource Source)
{
QMutexLocker locker(&mCmdQueueMutex);
PDebugCommand pCmd = std::make_shared<DebugCommand>();
pCmd->command = Command;
pCmd->params = Params;
pCmd->source = Source;
mCmdQueue.enqueue(pCmd);
// if (!mCmdRunning)
// runNextCmd();
}
void DebugReader::registerInferiorStoppedCommand(const QString &Command, const QString &Params)
{
QMutexLocker locker(&mCmdQueueMutex);
PDebugCommand pCmd = std::make_shared<DebugCommand>();
pCmd->command = Command;
pCmd->params = Params;
pCmd->source = DebugCommandSource::Other;
mInferiorStoppedHookCommands.append(pCmd);
}
void DebugReader::clearCmdQueue()
{ {
QMutexLocker locker(&mCmdQueueMutex); QMutexLocker locker(&mCmdQueueMutex);
mCmdQueue.clear(); mCmdQueue.clear();
} }
void DebugReader::processConsoleOutput(const QByteArray& line) void DebuggerClient::processConsoleOutput(const QByteArray& line)
{ {
if (line.length()>3 && line.startsWith("~\"") && line.endsWith("\"")) { if (line.length()>3 && line.startsWith("~\"") && line.endsWith("\"")) {
QByteArray s=line.mid(2,line.length()-3); QByteArray s=line.mid(2,line.length()-3);
@ -1119,7 +1096,7 @@ void DebugReader::processConsoleOutput(const QByteArray& line)
} }
} }
void DebugReader::processLogOutput(const QByteArray &line) void DebuggerClient::processLogOutput(const QByteArray &line)
{ {
if (mDebugger->debugInfosUsingUTF8() && line.endsWith(": No such file or directory.\n\"")) { if (mDebugger->debugInfosUsingUTF8() && line.endsWith(": No such file or directory.\n\"")) {
QByteArray newLine = line; QByteArray newLine = line;
@ -1133,7 +1110,7 @@ void DebugReader::processLogOutput(const QByteArray &line)
} }
} }
void DebugReader::processResult(const QByteArray &result) void DebuggerClient::processResult(const QByteArray &result)
{ {
GDBMIResultParser parser; GDBMIResultParser parser;
GDBMIResultType resultType; GDBMIResultType resultType;
@ -1186,7 +1163,7 @@ void DebugReader::processResult(const QByteArray &result)
} }
void DebugReader::processExecAsyncRecord(const QByteArray &line) void DebuggerClient::processExecAsyncRecord(const QByteArray &line)
{ {
QByteArray result; QByteArray result;
GDBMIResultParser::ParseObject multiValues; GDBMIResultParser::ParseObject multiValues;
@ -1260,7 +1237,7 @@ void DebugReader::processExecAsyncRecord(const QByteArray &line)
} }
} }
void DebugReader::processError(const QByteArray &errorLine) void DebuggerClient::processError(const QByteArray &errorLine)
{ {
QString s = QString::fromLocal8Bit(errorLine); QString s = QString::fromLocal8Bit(errorLine);
mConsoleOutput.append(s); mConsoleOutput.append(s);
@ -1272,7 +1249,7 @@ void DebugReader::processError(const QByteArray &errorLine)
} }
static QRegularExpression reGdbSourceLine("^(\\d)+\\s+in\\s+(.+)$"); static QRegularExpression reGdbSourceLine("^(\\d)+\\s+in\\s+(.+)$");
void DebugReader::processResultRecord(const QByteArray &line) void DebuggerClient::processResultRecord(const QByteArray &line)
{ {
if (line.startsWith("^exit")) { if (line.startsWith("^exit")) {
mProcessExited = true; mProcessExited = true;
@ -1337,7 +1314,7 @@ void DebugReader::processResultRecord(const QByteArray &line)
} }
} }
void DebugReader::processDebugOutput(const QByteArray& debugOutput) void DebuggerClient::processDebugOutput(const QByteArray& debugOutput)
{ {
// Only update once per update at most // Only update once per update at most
//WatchView.Items.BeginUpdate; //WatchView.Items.BeginUpdate;
@ -1385,7 +1362,7 @@ void DebugReader::processDebugOutput(const QByteArray& debugOutput)
mFullOutput.clear(); mFullOutput.clear();
} }
void DebugReader::runInferiorStoppedHook() void DebuggerClient::runInferiorStoppedHook()
{ {
QMutexLocker locker(&mCmdQueueMutex); QMutexLocker locker(&mCmdQueueMutex);
foreach (const PDebugCommand& cmd, mInferiorStoppedHookCommands) { foreach (const PDebugCommand& cmd, mInferiorStoppedHookCommands) {
@ -1393,7 +1370,7 @@ void DebugReader::runInferiorStoppedHook()
} }
} }
void DebugReader::runNextCmd() void DebuggerClient::runNextCmd()
{ {
QMutexLocker locker(&mCmdQueueMutex); QMutexLocker locker(&mCmdQueueMutex);
@ -1406,7 +1383,7 @@ void DebugReader::runNextCmd()
if (mCmdQueue.isEmpty()) { if (mCmdQueue.isEmpty()) {
if (mDebugger->useDebugServer() && mInferiorRunning && !mAsyncUpdated) { if (mDebugger->useDebugServer() && mInferiorRunning && !mAsyncUpdated) {
mAsyncUpdated = true; mAsyncUpdated = true;
QTimer::singleShot(50,this,&DebugReader::asyncUpdate); QTimer::singleShot(50,this,&DebuggerClient::asyncUpdate);
} }
return; return;
} }
@ -1451,7 +1428,6 @@ void DebugReader::runNextCmd()
emit writeToDebugFailed(); emit writeToDebugFailed();
} }
// if devDebugger.ShowCommandLog or pCmd^.ShowInConsole then begin
if (pSettings->debugger().enableDebugConsole() ) { if (pSettings->debugger().enableDebugConsole() ) {
//update debug console //update debug console
if (pSettings->debugger().showDetailLog() if (pSettings->debugger().showDetailLog()
@ -1461,7 +1437,7 @@ void DebugReader::runNextCmd()
} }
} }
QStringList DebugReader::tokenize(const QString &s) QStringList DebuggerClient::tokenize(const QString &s)
{ {
QStringList result; QStringList result;
int tStart,tEnd; int tStart,tEnd;
@ -1557,7 +1533,7 @@ QStringList DebugReader::tokenize(const QString &s)
return result; return result;
} }
bool DebugReader::outputTerminated(const QByteArray &text) bool DebuggerClient::outputTerminated(const QByteArray &text)
{ {
QStringList lines = textToLines(QString::fromUtf8(text)); QStringList lines = textToLines(QString::fromUtf8(text));
foreach (const QString& line,lines) { foreach (const QString& line,lines) {
@ -1567,7 +1543,7 @@ bool DebugReader::outputTerminated(const QByteArray &text)
return false; return false;
} }
void DebugReader::handleBreakpoint(const GDBMIResultParser::ParseObject& breakpoint) void DebuggerClient::handleBreakpoint(const GDBMIResultParser::ParseObject& breakpoint)
{ {
QString filename; QString filename;
// gdb use system encoding for file path // gdb use system encoding for file path
@ -1580,7 +1556,7 @@ void DebugReader::handleBreakpoint(const GDBMIResultParser::ParseObject& breakpo
emit breakpointInfoGetted(filename, line , number); emit breakpointInfoGetted(filename, line , number);
} }
void DebugReader::handleFrame(const GDBMIResultParser::ParseValue &frame) void DebuggerClient::handleFrame(const GDBMIResultParser::ParseValue &frame)
{ {
if (frame.isValid()) { if (frame.isValid()) {
GDBMIResultParser::ParseObject frameObj = frame.object(); GDBMIResultParser::ParseObject frameObj = frame.object();
@ -1598,7 +1574,7 @@ void DebugReader::handleFrame(const GDBMIResultParser::ParseValue &frame)
} }
} }
void DebugReader::handleStack(const QList<GDBMIResultParser::ParseValue> & stack) void DebuggerClient::handleStack(const QList<GDBMIResultParser::ParseValue> & stack)
{ {
mDebugger->backtraceModel()->clear(); mDebugger->backtraceModel()->clear();
foreach (const GDBMIResultParser::ParseValue& frameValue, stack) { foreach (const GDBMIResultParser::ParseValue& frameValue, stack) {
@ -1616,7 +1592,7 @@ void DebugReader::handleStack(const QList<GDBMIResultParser::ParseValue> & stack
} }
} }
void DebugReader::handleLocalVariables(const QList<GDBMIResultParser::ParseValue> &variables) void DebuggerClient::handleLocalVariables(const QList<GDBMIResultParser::ParseValue> &variables)
{ {
QStringList locals; QStringList locals;
foreach (const GDBMIResultParser::ParseValue& varValue, variables) { foreach (const GDBMIResultParser::ParseValue& varValue, variables) {
@ -1633,12 +1609,12 @@ void DebugReader::handleLocalVariables(const QList<GDBMIResultParser::ParseValue
emit localsUpdated(locals); emit localsUpdated(locals);
} }
void DebugReader::handleEvaluation(const QString &value) void DebuggerClient::handleEvaluation(const QString &value)
{ {
emit evalUpdated(value); emit evalUpdated(value);
} }
void DebugReader::handleMemory(const QList<GDBMIResultParser::ParseValue> &rows) void DebuggerClient::handleMemory(const QList<GDBMIResultParser::ParseValue> &rows)
{ {
QStringList memory; QStringList memory;
foreach (const GDBMIResultParser::ParseValue& row, rows) { foreach (const GDBMIResultParser::ParseValue& row, rows) {
@ -1654,7 +1630,7 @@ void DebugReader::handleMemory(const QList<GDBMIResultParser::ParseValue> &rows)
emit memoryUpdated(memory); emit memoryUpdated(memory);
} }
void DebugReader::handleRegisterNames(const QList<GDBMIResultParser::ParseValue> &names) void DebuggerClient::handleRegisterNames(const QList<GDBMIResultParser::ParseValue> &names)
{ {
QStringList nameList; QStringList nameList;
foreach (const GDBMIResultParser::ParseValue& nameValue, names) { foreach (const GDBMIResultParser::ParseValue& nameValue, names) {
@ -1665,7 +1641,7 @@ void DebugReader::handleRegisterNames(const QList<GDBMIResultParser::ParseValue>
emit registerNamesUpdated(nameList); emit registerNamesUpdated(nameList);
} }
void DebugReader::handleRegisterValue(const QList<GDBMIResultParser::ParseValue> &values) void DebuggerClient::handleRegisterValue(const QList<GDBMIResultParser::ParseValue> &values)
{ {
QHash<int,QString> result; QHash<int,QString> result;
foreach (const GDBMIResultParser::ParseValue& val, values) { foreach (const GDBMIResultParser::ParseValue& val, values) {
@ -1683,7 +1659,7 @@ void DebugReader::handleRegisterValue(const QList<GDBMIResultParser::ParseValue>
emit registerValuesUpdated(result); emit registerValuesUpdated(result);
} }
void DebugReader::handleCreateVar(const GDBMIResultParser::ParseObject &multiVars) void DebuggerClient::handleCreateVar(const GDBMIResultParser::ParseObject &multiVars)
{ {
if (!mCurrentCmd) if (!mCurrentCmd)
return; return;
@ -1696,7 +1672,7 @@ void DebugReader::handleCreateVar(const GDBMIResultParser::ParseObject &multiVar
emit varCreated(expression,name,numChild,value,type,hasMore); emit varCreated(expression,name,numChild,value,type,hasMore);
} }
void DebugReader::handleListVarChildren(const GDBMIResultParser::ParseObject &multiVars) void DebuggerClient::handleListVarChildren(const GDBMIResultParser::ParseObject &multiVars)
{ {
if (!mCurrentCmd) if (!mCurrentCmd)
return; return;
@ -1723,7 +1699,7 @@ void DebugReader::handleListVarChildren(const GDBMIResultParser::ParseObject &mu
} }
} }
void DebugReader::handleUpdateVarValue(const QList<GDBMIResultParser::ParseValue> &changes) void DebuggerClient::handleUpdateVarValue(const QList<GDBMIResultParser::ParseValue> &changes)
{ {
foreach (const GDBMIResultParser::ParseValue& value, changes) { foreach (const GDBMIResultParser::ParseValue& value, changes) {
GDBMIResultParser::ParseObject obj = value.object(); GDBMIResultParser::ParseObject obj = value.object();
@ -1741,7 +1717,7 @@ void DebugReader::handleUpdateVarValue(const QList<GDBMIResultParser::ParseValue
//emit varsValueUpdated(); //emit varsValueUpdated();
} }
QByteArray DebugReader::removeToken(const QByteArray &line) QByteArray DebuggerClient::removeToken(const QByteArray &line)
{ {
int p=0; int p=0;
while (p<line.length()) { while (p<line.length()) {
@ -1756,7 +1732,7 @@ QByteArray DebugReader::removeToken(const QByteArray &line)
return line; return line;
} }
void DebugReader::asyncUpdate() void DebuggerClient::asyncUpdate()
{ {
QMutexLocker locker(&mCmdQueueMutex); QMutexLocker locker(&mCmdQueueMutex);
if (mCmdQueue.isEmpty()) { if (mCmdQueue.isEmpty()) {
@ -1765,172 +1741,91 @@ void DebugReader::asyncUpdate()
mAsyncUpdated = false; mAsyncUpdated = false;
} }
const QStringList &DebugReader::binDirs() const const QStringList &DebuggerClient::binDirs() const
{ {
return mBinDirs; return mBinDirs;
} }
void DebugReader::addBinDirs(const QStringList &binDirs) void DebuggerClient::addBinDirs(const QStringList &binDirs)
{ {
mBinDirs.append(binDirs); mBinDirs.append(binDirs);
} }
void DebugReader::addBinDir(const QString &binDir) void DebuggerClient::addBinDir(const QString &binDir)
{ {
mBinDirs.append(binDir); mBinDirs.append(binDir);
} }
const QString &DebugReader::signalMeaning() const const QString &DebuggerClient::signalMeaning() const
{ {
return mSignalMeaning; return mSignalMeaning;
} }
const QString &DebugReader::signalName() const const QString &DebuggerClient::signalName() const
{ {
return mSignalName; return mSignalName;
} }
bool DebugReader::inferiorRunning() const bool DebuggerClient::inferiorRunning() const
{ {
return mInferiorRunning; return mInferiorRunning;
} }
const QStringList &DebugReader::fullOutput() const const QStringList &DebuggerClient::fullOutput() const
{ {
return mFullOutput; return mFullOutput;
} }
bool DebugReader::receivedSFWarning() const bool DebuggerClient::receivedSFWarning() const
{ {
return mReceivedSFWarning; return mReceivedSFWarning;
} }
bool DebugReader::updateCPUInfo() const bool DebuggerClient::updateCPUInfo() const
{ {
return mUpdateCPUInfo; return mUpdateCPUInfo;
} }
const PDebugCommand &DebugReader::currentCmd() const const PDebugCommand &DebuggerClient::currentCmd() const
{ {
return mCurrentCmd; return mCurrentCmd;
} }
const QStringList &DebugReader::consoleOutput() const const QStringList &DebuggerClient::consoleOutput() const
{ {
return mConsoleOutput; return mConsoleOutput;
} }
bool DebugReader::signalReceived() const bool DebuggerClient::signalReceived() const
{ {
return mSignalReceived; return mSignalReceived;
} }
bool DebugReader::processExited() const bool DebuggerClient::processExited() const
{ {
return mProcessExited; return mProcessExited;
} }
QString DebugReader::debuggerPath() const QString DebuggerClient::debuggerPath() const
{ {
return mDebuggerPath; return mDebuggerPath;
} }
void DebugReader::setDebuggerPath(const QString &debuggerPath) void DebuggerClient::setDebuggerPath(const QString &debuggerPath)
{ {
mDebuggerPath = debuggerPath; mDebuggerPath = debuggerPath;
} }
void DebugReader::stopDebug() bool DebuggerClient::commandRunning()
{
mStop = true;
}
bool DebugReader::commandRunning()
{ {
return !mCmdQueue.isEmpty(); return !mCmdQueue.isEmpty();
} }
void DebugReader::waitStart() void DebuggerClient::waitStart()
{ {
mStartSemaphore.acquire(1); mStartSemaphore.acquire(1);
} }
void DebugReader::run()
{
mStop = false;
mInferiorRunning = false;
mProcessExited = false;
mErrorOccured = false;
QString cmd = mDebuggerPath;
// QString arguments = "--annotate=2";
QStringList arguments{"--interpret=mi", "--silent"};
QString workingDir = QFileInfo(mDebuggerPath).path();
mProcess = std::make_shared<QProcess>();
auto action = finally([&]{
mProcess.reset();
});
mProcess->setProgram(cmd);
mProcess->setArguments(arguments);
mProcess->setProcessChannelMode(QProcess::MergedChannels);
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
QString path = env.value("PATH");
QStringList pathAdded = mBinDirs;
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,
[&](){
mErrorOccured= 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 (mErrorOccured)
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 (mErrorOccured) {
emit processError(mProcess->error());
}
}
BreakpointModel::BreakpointModel(QObject *parent):QAbstractTableModel(parent), BreakpointModel::BreakpointModel(QObject *parent):QAbstractTableModel(parent),
mIsForProject(false) mIsForProject(false)

View File

@ -295,11 +295,11 @@ private:
}; };
class DebugReader; class DebuggerClient;
class DebugTarget; class DebugTarget;
class Editor; class Editor;
using PDebugReader = std::shared_ptr<DebugReader>; using PDebugReader = std::shared_ptr<DebuggerClient>;
class Debugger : public QObject class Debugger : public QObject
{ {
@ -417,7 +417,7 @@ private:
std::shared_ptr<WatchModel> mWatchModel; std::shared_ptr<WatchModel> mWatchModel;
std::shared_ptr<RegisterModel> mRegisterModel; std::shared_ptr<RegisterModel> mRegisterModel;
std::shared_ptr<MemoryModel> mMemoryModel; std::shared_ptr<MemoryModel> mMemoryModel;
DebugReader *mReader; DebuggerClient *mClient;
DebugTarget *mTarget; DebugTarget *mTarget;
bool mForceUTF8; bool mForceUTF8;
bool mDebugInfosUsingUTF8; bool mDebugInfosUsingUTF8;
@ -462,48 +462,29 @@ protected:
void run() override; void run() override;
}; };
class DebugReader : public QThread class DebuggerClient : public QThread
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit DebugReader(Debugger* debugger, QObject *parent = nullptr); explicit DebuggerClient(Debugger* debugger, QObject *parent = nullptr);
void postCommand(const QString &Command, const QString &Params, DebugCommandSource Source); virtual void postCommand(const QString &Command, const QString &Params, DebugCommandSource Source) = 0;
void registerInferiorStoppedCommand(const QString &Command, const QString &Params); virtual void registerInferiorStoppedCommand(const QString &Command, const QString &Params) = 0;
virtual void stopDebug() = 0;
bool commandRunning();
QString debuggerPath() const; QString debuggerPath() const;
void setDebuggerPath(const QString &debuggerPath); void setDebuggerPath(const QString &debuggerPath);
void stopDebug();
bool commandRunning();
void waitStart(); void waitStart();
bool inferiorPaused() const;
bool processExited() const; bool processExited() const;
bool signalReceived() const; bool signalReceived() const;
const QStringList &consoleOutput() const; const QStringList &consoleOutput() const;
int breakPointLine() const;
const QString &breakPointFile() const;
const PDebugCommand &currentCmd() const; const PDebugCommand &currentCmd() const;
bool updateCPUInfo() const; bool updateCPUInfo() const;
bool updateLocals() const;
const QStringList &localsValue() const;
bool evalReady() const;
const QString &evalValue() const;
bool updateMemory() const;
const QStringList &memoryValue() const;
bool receivedSFWarning() const; bool receivedSFWarning() const;
const QStringList &fullOutput() const; const QStringList &fullOutput() const;
@ -585,22 +566,24 @@ private:
QByteArray removeToken(const QByteArray& line); QByteArray removeToken(const QByteArray& line);
private slots: private slots:
void asyncUpdate(); void asyncUpdate();
private: protected:
Debugger *mDebugger;
QString mDebuggerPath;
#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
QSemaphore mStartSemaphore;
QQueue<PDebugCommand> mCmdQueue; QQueue<PDebugCommand> mCmdQueue;
QList<PDebugCommand> mInferiorStoppedHookCommands;
private:
Debugger *mDebugger;
QString mDebuggerPath;
QSemaphore mStartSemaphore;
bool mErrorOccured; bool mErrorOccured;
bool mAsyncUpdated; bool mAsyncUpdated;
//fOnInvalidateAllVars: TInvalidateAllVarsEvent; //fOnInvalidateAllVars: TInvalidateAllVarsEvent;
bool mCmdRunning; bool mCmdRunning;
PDebugCommand mCurrentCmd; PDebugCommand mCurrentCmd;
std::shared_ptr<QProcess> mProcess;
QStringList mBinDirs; QStringList mBinDirs;
QMap<QString,QStringList> mFileCache; QMap<QString,QStringList> mFileCache;
@ -610,7 +593,6 @@ private:
QString mSignalMeaning; QString mSignalMeaning;
// //
QList<PDebugCommand> mInferiorStoppedHookCommands;
bool mInferiorRunning; bool mInferiorRunning;
bool mProcessExited; bool mProcessExited;
@ -624,10 +606,6 @@ private:
QString mCurrentFile; QString mCurrentFile;
QStringList mConsoleOutput; QStringList mConsoleOutput;
QStringList mFullOutput; QStringList mFullOutput;
bool mStop;
// QThread interface
protected:
void run() override;
}; };
#endif // DEBUGGER_H #endif // DEBUGGER_H

View File

@ -0,0 +1,132 @@
/*
* 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/>.
*/
#include "gdbmidebugger.h"
#include "../utils.h"
#include <QFileInfo>
GDBMIDebuggerClient::GDBMIDebuggerClient(Debugger *debugger, QObject *parent):
DebuggerClient(debugger, parent)
{
}
void GDBMIDebuggerClient::postCommand(const QString &Command, const QString &Params,
DebugCommandSource Source)
{
QMutexLocker locker(&mCmdQueueMutex);
PDebugCommand pCmd = std::make_shared<DebugCommand>();
pCmd->command = Command;
pCmd->params = Params;
pCmd->source = Source;
mCmdQueue.enqueue(pCmd);
// if (!mCmdRunning)
// runNextCmd();
}
void GDBMIDebuggerClient::registerInferiorStoppedCommand(const QString &Command, const QString &Params)
{
QMutexLocker locker(&mCmdQueueMutex);
PDebugCommand pCmd = std::make_shared<DebugCommand>();
pCmd->command = Command;
pCmd->params = Params;
pCmd->source = DebugCommandSource::Other;
mInferiorStoppedHookCommands.append(pCmd);
}
void GDBMIDebuggerClient::stopDebug()
{
mStop = true;
}
void GDBMIDebuggerClient::run()
{
mStop = false;
mInferiorRunning = false;
mProcessExited = false;
mErrorOccured = 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);
mProcess->setProcessChannelMode(QProcess::MergedChannels);
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,
[&](){
mErrorOccured= 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 (mErrorOccured)
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 (mErrorOccured) {
emit processError(mProcess->error());
}
}

View File

@ -0,0 +1,42 @@
/*
* 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 GDBMI_DEBUGGER_H
#define GDBMI_DEBUGGER_H
#include "debugger.h"
#include <QProcess>
#include <memory>
class GDBMIDebuggerClient: public DebuggerClient {
Q_OBJECT
public:
explicit GDBMIDebuggerClient(Debugger* debugger, QObject *parent = nullptr);
// 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;
// QThread interface
protected:
void run() override;
private:
bool mStop;
std::shared_ptr<QProcess> mProcess;
};
#endif // GDBMI_DEBUGGER_H

View File

@ -125,4 +125,4 @@ public:
} }
#endif // SYNEDITASMHIGHLIGHTER_H #endif // QSYNEDIT_ASM_SYNTAXER_H

View File

@ -221,4 +221,4 @@ public:
} }
#endif // SYNEDITCPPHIGHLIGHTER_H #endif // QSYNEDIT_CPP_SYNTAXER_H

View File

@ -186,4 +186,4 @@ public:
}; };
} }
#endif // SYNEDITGLSLHIGHLIGHTER_H #endif // QSYNEDIT_GLSL_SYNTAXER_H

View File

@ -175,4 +175,4 @@ public:
} }
#endif // SYNEDITCPPHIGHLIGHTER_H #endif // QSYNEDIT_LUA_SYNTAXER_H

View File

@ -155,4 +155,4 @@ public:
}; };
} }
#endif // MAKEFILE_H #endif // QSYNEDIT_MAKEFILE_SYNTAXER_H

View File

@ -195,4 +195,4 @@ private:
using PSyntaxer = std::shared_ptr<Syntaxer>; using PSyntaxer = std::shared_ptr<Syntaxer>;
using SyntaxerList = QVector<PSyntaxer>; using SyntaxerList = QVector<PSyntaxer>;
} }
#endif // SYNHIGHLIGTERBASE_H #endif // QSYNEDIT_SYNTAXER_H

View File

@ -84,4 +84,4 @@ public:
}; };
} }
#endif // MAKEFILE_H #endif // QSYNEDIT_TEXTFILE_SYNTAXER_H