work save

This commit is contained in:
Roy Qu 2021-11-23 21:08:33 +08:00
parent d3abf822fb
commit 9fd06a9837
4 changed files with 221 additions and 128 deletions

View File

@ -12,6 +12,9 @@
#include <QPlainTextEdit> #include <QPlainTextEdit>
#include <QDebug> #include <QDebug>
#include <QDir> #include <QDir>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
Debugger::Debugger(QObject *parent) : QObject(parent) Debugger::Debugger(QObject *parent) : QObject(parent)
{ {
@ -63,6 +66,7 @@ bool Debugger::start()
connect(this, &Debugger::localsReady,pMainWindow,&MainWindow::onLocalsReady); connect(this, &Debugger::localsReady,pMainWindow,&MainWindow::onLocalsReady);
connect(mReader, &DebugReader::cmdStarted,pMainWindow, &MainWindow::disableDebugActions); connect(mReader, &DebugReader::cmdStarted,pMainWindow, &MainWindow::disableDebugActions);
connect(mReader, &DebugReader::cmdFinished,pMainWindow, &MainWindow::enableDebugActions); connect(mReader, &DebugReader::cmdFinished,pMainWindow, &MainWindow::enableDebugActions);
connect(mReader, &DebugReader::breakpointInfoGetted, mBreakpointModel, connect(mReader, &DebugReader::breakpointInfoGetted, mBreakpointModel,
&BreakpointModel::updateBreakpointNumber); &BreakpointModel::updateBreakpointNumber);
@ -455,23 +459,17 @@ void Debugger::syncFinishedParsing()
} }
// An evaluation variable has been processed. Forward the results // An evaluation variable has been processed. Forward the results
if (mReader->doevalready) { if (mReader->evalReady()) {
//pMainWindow->updateDebugEval(mReader->mEvalValue); //pMainWindow->updateDebugEval(mReader->mEvalValue);
emit evalValueReady(mReader->mEvalValue); emit evalValueReady(mReader->evalValue());
mReader->mEvalValue="";
mReader->doevalready = false;
} }
if (mReader->doupdatememoryview) { if (mReader->updateMemory()) {
emit memoryExamineReady(mReader->mMemoryValue); emit memoryExamineReady(mReader->memoryValue());
mReader->mMemoryValue.clear();
mReader->doupdatememoryview=false;
} }
if (mReader->doupdatelocal) { if (mReader->updateLocals()) {
emit localsReady(mReader->mLocalsValue); emit localsReady(mReader->localsValue());
mReader->mLocalsValue.clear();
mReader->doupdatelocal=false;
} }
// show command output // show command output
@ -521,16 +519,17 @@ void Debugger::syncFinishedParsing()
} }
} }
if (mReader->doupdateexecution) { if (mReader->updateExecution()) {
if (mReader->mCurrentCmd && mReader->mCurrentCmd->source == DebugCommandSource::Console) { if (mReader->currentCmd() && mReader->currentCmd()->source == DebugCommandSource::Console) {
pMainWindow->setActiveBreakpoint(mReader->mBreakPointFile, mReader->mBreakPointLine,false); pMainWindow->setActiveBreakpoint(mReader->breakPointFile(), mReader->breakPointLine(),false);
} else { } else {
pMainWindow->setActiveBreakpoint(mReader->mBreakPointFile, mReader->mBreakPointLine); pMainWindow->setActiveBreakpoint(mReader->breakPointFile(), mReader->breakPointLine());
} }
refreshWatchVars(); // update variable information refreshWatchVars(); // update variable information
} }
if (mReader->doreceivedsignal) { if (mReader->signalReceived()) {
//SignalDialog := CreateMessageDialog(fSignal, mtError, [mbOk]); //SignalDialog := CreateMessageDialog(fSignal, mtError, [mbOk]);
//SignalCheck := TCheckBox.Create(SignalDialog); //SignalCheck := TCheckBox.Create(SignalDialog);
@ -563,7 +562,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->doupdatecpuwindow && !spawnedcpuform) && (pMainWindow->cpuDialog()!=nullptr)) { if ((mReader->updateCPUInfo() && !spawnedcpuform) && (pMainWindow->cpuDialog()!=nullptr)) {
pMainWindow->cpuDialog()->updateInfo(); pMainWindow->cpuDialog()->updateInfo();
} }
} }
@ -903,86 +902,6 @@ void DebugReader::handleExit()
doprocessexited=true; doprocessexited=true;
} }
void DebugReader::handleFrames()
{
QString s = getNextLine();
// Is this a backtrace dump?
if (s.startsWith("#")) {
if (s.startsWith("#0")) {
mDebugger->backtraceModel()->clear();
}
// Find function name
if (!findAnnotation(AnnotationType::TFrameFunctionName))
return;
PTrace trace = std::make_shared<Trace>();
trace->funcname = getNextLine();
// Find argument list start
if (!findAnnotation(AnnotationType::TFrameArgs))
return;
// Arguments are either () or detailed list
s = getNextLine();
while (peekNextAnnotation() == AnnotationType::TArgBegin) {
// argument name
if (!findAnnotation(AnnotationType::TArgBegin))
return;
s = s + getNextLine();
// =
if (!findAnnotation(AnnotationType::TArgNameEnd))
return;
s = s + ' ' + getNextLine() + ' '; // should be =
// argument value
if (!findAnnotation(AnnotationType::TArgValue))
return;
s = s + getNextLine();
// argument end
if (!findAnnotation(AnnotationType::TArgEnd))
return;
s = s + getNextLine();
}
trace->funcname = trace->funcname + s.trimmed();
// source info
if (peekNextAnnotation() == AnnotationType::TFrameSourceBegin) {
// Find filename
if (!findAnnotation(AnnotationType::TFrameSourceFile))
return;
trace->filename = getNextLine();
// find line
if (!findAnnotation(AnnotationType::TFrameSourceLine))
return;
trace->line = getNextLine().trimmed().toInt();
} else {
trace->filename = "";
trace->line = 0;
}
mDebugger->backtraceModel()->addTrace(trace);
// Skip over the remaining frame part...
if (!findAnnotation(AnnotationType::TFrameEnd))
return;
// Not another one coming? Done!
if (peekNextAnnotation() != AnnotationType::TFrameBegin) {
// End of stack trace dump!
dobacktraceready = true;
}
} else
doupdatecpuwindow = true;
}
void DebugReader::handleLocalOutput() void DebugReader::handleLocalOutput()
{ {
// name(spaces)hexvalue(tab)decimalvalue // name(spaces)hexvalue(tab)decimalvalue
@ -1167,9 +1086,22 @@ void DebugReader::processResult(const QByteArray &result)
if (!parseOk) if (!parseOk)
return; return;
switch(resultType) { switch(resultType) {
case GDBMIResultType::BreakpointTable:
case GDBMIResultType::Frame:
case GDBMIResultType::Locals:
break;
case GDBMIResultType::Breakpoint: case GDBMIResultType::Breakpoint:
handleBreakpoint(parseValue.object()); handleBreakpoint(parseValue.object());
return; return;
case GDBMIResultType::FrameStack:
handleStack(parseValue.array());
return;
case GDBMIResultType::LocalVariables:
handleLocalVariables(parseValue.array());
return;
case GDBMIResultType::Evaluation:
handleEvaluation(parseValue.value());
return;
} }
QByteArray name = result.mid(0,pos); QByteArray name = result.mid(0,pos);
@ -1227,13 +1159,12 @@ void DebugReader::processExecAsyncRecord(const QByteArray &line)
mProcessExited = true; mProcessExited = true;
return; return;
} }
mUpdateExecution = true;
mUpdateCPUInfo = true;
mBreakPointFile = multiValues["fullname"].pathValue();
mBreakPointLine = multiValues["line"].intValue();
if (reason == "signal-received") { if (reason == "signal-received") {
//todo: signal received mSignalReceived = true;
return;
}
if (reason == "breakpoint-hit") {
//todo: signal received
return;
} }
} }
} }
@ -1282,10 +1213,16 @@ void DebugReader::processDebugOutput(const QByteArray& debugOutput)
emit parseStarted(); emit parseStarted();
mConsoleOutput.clear(); mConsoleOutput.clear();
mLocalsValue.clear();
mEvalValue.clear();
mMemoryValue.clear();
//try mUpdateExecution = false;
mSignalReceived = false;
mUpdateCPUInfo = false;
mUpdateLocals = false;
mEvalReady = false;
dobacktraceready = false;
dodisassemblerready = false; dodisassemblerready = false;
doregistersready = false; doregistersready = false;
doevalready = false; doevalready = false;
@ -1725,12 +1662,58 @@ QStringList DebugReader::tokenize(const QString &s)
void DebugReader::handleBreakpoint(const GDBMIResultParser::ParseObject& breakpoint) void DebugReader::handleBreakpoint(const GDBMIResultParser::ParseObject& breakpoint)
{ {
// gdb use system encoding for file path // gdb use system encoding for file path
QString filename = QFileInfo(QString::fromLocal8Bit(breakpoint["filename"].value())).absoluteFilePath(); QString filename = breakpoint["fullname"].value();
int line = breakpoint["line"].intValue(); int line = breakpoint["line"].intValue();
int number = breakpoint["number"].intValue(); int number = breakpoint["number"].intValue();
emit breakpointInfoGetted(filename, line , number); emit breakpointInfoGetted(filename, line , number);
} }
void DebugReader::handleStack(const QList<GDBMIResultParser::ParseValue> & stack)
{
mDebugger->backtraceModel()->clear();
foreach (const GDBMIResultParser::ParseValue& frameValue, stack) {
GDBMIResultParser::ParseObject frameObject = frameValue.object();
PTrace trace = std::make_shared<Trace>();
trace->funcname = frameObject["func"].value();
trace->filename = frameObject["fullname"].pathValue();
trace->line = frameObject["fullname"].intValue();
trace->level = frameObject["level"].intValue(0);
trace->address = frameObject["addr"].value();
mDebugger->backtraceModel()->addTrace(trace);
}
}
void DebugReader::handleLocalVariables(const QList<GDBMIResultParser::ParseValue> &variables)
{
mUpdateLocals=true;
foreach (const GDBMIResultParser::ParseValue& varValue, variables) {
GDBMIResultParser::ParseObject varObject = varValue.object();
mLocalsValue.append(QString("%1 = %2")
.arg(varObject["name"].value(),varObject["value"].value()));
}
}
void DebugReader::handleEvaluation(const QString &value)
{
mEvalReady = true;
mEvalValue = value;
}
void DebugReader::handleMemory(const QList<GDBMIResultParser::ParseValue> &rows)
{
mUpdateMemory = true;
foreach (const GDBMIResultParser::ParseValue& row, rows) {
GDBMIResultParser::ParseObject rowObject = row.object();
QList<GDBMIResultParser::ParseValue> data = rowObject["data"].array();
QStringList values;
foreach (const GDBMIResultParser::ParseValue& val, data) {
values.append(val.value());
}
mLocalsValue.append(QString("%1 %2")
.arg(rowObject["addr"].value(),values.join(" ")));
}
}
QByteArray DebugReader::removeToken(const QByteArray &line) QByteArray DebugReader::removeToken(const QByteArray &line)
{ {
int p=0; int p=0;
@ -1746,6 +1729,71 @@ QByteArray DebugReader::removeToken(const QByteArray &line)
return line; return line;
} }
const QStringList &DebugReader::memoryValue() const
{
return mMemoryValue;
}
bool DebugReader::updateMemory() const
{
return mUpdateMemory;
}
const QString &DebugReader::evalValue() const
{
return mEvalValue;
}
bool DebugReader::evalReady() const
{
return mEvalReady;
}
const QStringList &DebugReader::localsValue() const
{
return mLocalsValue;
}
bool DebugReader::updateLocals() const
{
return mUpdateLocals;
}
bool DebugReader::updateCPUInfo() const
{
return mUpdateCPUInfo;
}
const PDebugCommand &DebugReader::currentCmd() const
{
return mCurrentCmd;
}
const QString &DebugReader::breakPointFile() const
{
return mBreakPointFile;
}
int DebugReader::breakPointLine() const
{
return mBreakPointLine;
}
const QStringList &DebugReader::consoleOutput() const
{
return mConsoleOutput;
}
bool DebugReader::signalReceived() const
{
return mSignalReceived;
}
bool DebugReader::updateExecution() const
{
return mUpdateExecution;
}
bool DebugReader::processExited() const bool DebugReader::processExited() const
{ {
return mProcessExited; return mProcessExited;
@ -1791,7 +1839,6 @@ bool DebugReader::waitStart()
mStartSemaphore.acquire(1); mStartSemaphore.acquire(1);
} }
void DebugReader::run() void DebugReader::run()
{ {
mStop = false; mStop = false;
@ -2056,6 +2103,7 @@ void BreakpointModel::updateBreakpointNumber(const QString &filename, int line,
foreach (PBreakpoint bp, mList) { foreach (PBreakpoint bp, mList) {
if (bp->filename == filename && bp->line == line) { if (bp->filename == filename && bp->line == line) {
bp->number = number; bp->number = number;
return;
} }
} }
} }

View File

@ -55,7 +55,9 @@ using PBreakpoint = std::shared_ptr<Breakpoint>;
struct Trace { struct Trace {
QString funcname; QString funcname;
QString filename; QString filename;
QString address;
int line; int line;
int level;
}; };
using PTrace = std::shared_ptr<Trace>; using PTrace = std::shared_ptr<Trace>;
@ -281,6 +283,31 @@ public:
bool processExited() const; bool processExited() const;
bool updateExecution() const;
bool signalReceived() const;
const QStringList &consoleOutput() const;
int breakPointLine() const;
const QString &breakPointFile() const;
const PDebugCommand &currentCmd() 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;
signals: signals:
void parseStarted(); void parseStarted();
@ -302,7 +329,6 @@ private:
void handleDisplay(); void handleDisplay();
void handleError(); void handleError();
void handleExit(); void handleExit();
void handleFrames();
void handleLocalOutput(); void handleLocalOutput();
void handleLocals(); void handleLocals();
void handleMemory(); void handleMemory();
@ -319,6 +345,10 @@ private:
QStringList tokenize(const QString& s); QStringList tokenize(const QString& s);
void handleBreakpoint(const GDBMIResultParser::ParseObject& breakpoint); void handleBreakpoint(const GDBMIResultParser::ParseObject& breakpoint);
void handleStack(const QList<GDBMIResultParser::ParseValue> & stack);
void handleLocalVariables(const QList<GDBMIResultParser::ParseValue> & variables);
void handleEvaluation(const QString& value);
void handleMemory(const QList<GDBMIResultParser::ParseValue> & rows);
void processConsoleOutput(const QByteArray& line); void processConsoleOutput(const QByteArray& line);
void processResult(const QByteArray& result); void processResult(const QByteArray& result);
void processExecAsyncRecord(const QByteArray& line); void processExecAsyncRecord(const QByteArray& line);
@ -345,16 +375,11 @@ private:
//fWatchView: TTreeView; //fWatchView: TTreeView;
int mIndex; int mIndex;
int mBreakPointLine;
QString mBreakPointFile;
QString mEvalValue;
QStringList mMemoryValue;
QStringList mLocalsValue;
QString mSignal; QString mSignal;
bool mUseUTF8; bool mUseUTF8;
// attempt to cut down on Synchronize calls // attempt to cut down on Synchronize calls
bool dobacktraceready;
bool dodisassemblerready; bool dodisassemblerready;
bool doregistersready; bool doregistersready;
bool doevalready; bool doevalready;
@ -363,12 +388,24 @@ private:
bool doreceivedsignal; bool doreceivedsignal;
bool doreceivedsfwarning; bool doreceivedsfwarning;
bool doupdatememoryview; bool doupdatememoryview;
bool doupdatelocal;
// //
bool mInferiorPaused; bool mInferiorPaused;
bool mProcessExited; bool mProcessExited;
bool mUpdateExecution;
bool mSignalReceived;
bool mUpdateCPUInfo;
bool mUpdateLocals;
bool mEvalReady;
bool mUpdateMemory;
QStringList mConsoleOutput; QStringList mConsoleOutput;
int mBreakPointLine;
QString mBreakPointFile;
QStringList mLocalsValue;
QString mEvalValue;
QStringList mMemoryValue;
bool mStop; bool mStop;
// QThread interface // QThread interface

View File

@ -1,5 +1,6 @@
#include "gdbmiresultparser.h" #include "gdbmiresultparser.h"
#include <QFileInfo>
#include <QList> #include <QList>
GDBMIResultParser::GDBMIResultParser() GDBMIResultParser::GDBMIResultParser()
@ -172,7 +173,7 @@ bool GDBMIResultParser::parseObject(const char *&p, ParseObject &obj)
return false; return false;
} }
bool GDBMIResultParser::parseArray(const char *&p, QList<GDBMIResultParser::ParseObject> &array) bool GDBMIResultParser::parseArray(const char *&p, QList<GDBMIResultParser::ParseValue> &array)
{ {
if (*p!='[') if (*p!='[')
return false; return false;
@ -180,10 +181,10 @@ bool GDBMIResultParser::parseArray(const char *&p, QList<GDBMIResultParser::Pars
if (*p!=']') { if (*p!=']') {
while (*p!=0) { while (*p!=0) {
skipSpaces(p); skipSpaces(p);
ParseObject obj; ParseValue val;
bool result = parseObject(p,obj); bool result = parseValue(p,val);
if (result) { if (result) {
array.append(obj); array.append(val);
} else { } else {
return false; return false;
} }
@ -236,7 +237,7 @@ const QByteArray &GDBMIResultParser::ParseValue::value() const
return mValue; return mValue;
} }
const QList<::GDBMIResultParser::ParseObject> &GDBMIResultParser::ParseValue::array() const const QList<::GDBMIResultParser::ParseValue> &GDBMIResultParser::ParseValue::array() const
{ {
Q_ASSERT(mType == ParseValueType::Array); Q_ASSERT(mType == ParseValueType::Array);
return mArray; return mArray;
@ -259,6 +260,12 @@ int GDBMIResultParser::ParseValue::intValue(int defaultValue) const
return defaultValue; return defaultValue;
} }
QString GDBMIResultParser::ParseValue::pathValue() const
{
Q_ASSERT(mType == ParseValueType::Value);
return QFileInfo(QString::fromLocal8Bit(mValue)).absoluteFilePath();
}
GDBMIResultParser::ParseValueType GDBMIResultParser::ParseValue::type() const GDBMIResultParser::ParseValueType GDBMIResultParser::ParseValue::type() const
{ {
return mType; return mType;
@ -281,7 +288,7 @@ GDBMIResultParser::ParseValue::ParseValue(const ParseObject &object):
{ {
} }
GDBMIResultParser::ParseValue::ParseValue(const QList<ParseObject> &array): GDBMIResultParser::ParseValue::ParseValue(const QList<ParseValue> &array):
mArray(array), mArray(array),
mType(ParseValueType::Array) mType(ParseValueType::Array)
{ {
@ -301,7 +308,7 @@ GDBMIResultParser::ParseValue &GDBMIResultParser::ParseValue::operator=(const Pa
mObject = object; mObject = object;
} }
GDBMIResultParser::ParseValue &GDBMIResultParser::ParseValue::operator=(const QList<ParseObject>& array) GDBMIResultParser::ParseValue &GDBMIResultParser::ParseValue::operator=(const QList<ParseValue>& array)
{ {
Q_ASSERT(mType == ParseValueType::NotAssigned); Q_ASSERT(mType == ParseValueType::NotAssigned);
mType = ParseValueType::Array; mType = ParseValueType::Array;

View File

@ -48,20 +48,21 @@ public:
explicit ParseValue(); explicit ParseValue();
explicit ParseValue(const QByteArray& value); explicit ParseValue(const QByteArray& value);
explicit ParseValue(const ParseObject &object); explicit ParseValue(const ParseObject &object);
explicit ParseValue(const QList<ParseObject>& array); explicit ParseValue(const QList<ParseValue>& array);
ParseValue(const ParseValue&) = delete; ParseValue(const ParseValue&) = delete;
const QByteArray &value() const; const QByteArray &value() const;
const QList<ParseObject> &array() const; const QList<ParseValue> &array() const;
const ParseObject &object() const; const ParseObject &object() const;
int intValue(int defaultValue=-1) const; int intValue(int defaultValue=-1) const;
QString pathValue() const;
ParseValueType type() const; ParseValueType type() const;
ParseValue& operator=(const QByteArray& value); ParseValue& operator=(const QByteArray& value);
ParseValue& operator=(const ParseObject& object); ParseValue& operator=(const ParseObject& object);
ParseValue& operator=(const QList<ParseObject>& array); ParseValue& operator=(const QList<ParseValue>& array);
ParseValue& operator=(const ParseValue& value); ParseValue& operator=(const ParseValue& value);
private: private:
QByteArray mValue; QByteArray mValue;
QList<ParseObject> mArray; QList<ParseValue> mArray;
ParseObject mObject; ParseObject mObject;
ParseValueType mType; ParseValueType mType;
}; };
@ -78,7 +79,7 @@ private:
bool parseValue(const char* &p, ParseValue& value); bool parseValue(const char* &p, ParseValue& value);
bool parseStringValue(const char*&p, QByteArray& stringValue); bool parseStringValue(const char*&p, QByteArray& stringValue);
bool parseObject(const char*&p, ParseObject& obj); bool parseObject(const char*&p, ParseObject& obj);
bool parseArray(const char*&p, QList<ParseObject>& array); bool parseArray(const char*&p, QList<ParseValue>& array);
void skipSpaces(const char* &p); void skipSpaces(const char* &p);
bool isNameChar(char ch); bool isNameChar(char ch);
bool isSpaceChar(char ch); bool isSpaceChar(char ch);