work save

This commit is contained in:
royqh1979@gmail.com 2021-11-10 17:05:37 +08:00
parent 71f5a7c056
commit bfd64312d9
3 changed files with 138 additions and 66 deletions

View File

@ -68,7 +68,7 @@ bool Debugger::start()
connect(mReader, &DebugReader::cmdFinished,pMainWindow, &MainWindow::enableDebugActions); connect(mReader, &DebugReader::cmdFinished,pMainWindow, &MainWindow::enableDebugActions);
mReader->start(); mReader->start();
mReader->mStartSemaphore.acquire(1); mReader->waitStart();
pMainWindow->updateAppTitle(); pMainWindow->updateAppTitle();
@ -450,7 +450,7 @@ void Debugger::syncFinishedParsing()
} }
// The program to debug has stopped. Stop the debugger // The program to debug has stopped. Stop the debugger
if (mReader->doprocessexited) { if (mReader->processExited()) {
stop(); stop();
return; return;
} }
@ -1151,21 +1151,103 @@ void DebugReader::handleValueHistoryValue()
doevalready = true; doevalready = true;
} }
AnnotationType DebugReader::peekNextAnnotation() void DebugReader::processConsoleOutput(const QString& line)
{ {
int indexBackup = mIndex; // do NOT modifiy curpos if (line.length()>3 && line.startsWith("~\"") && line.endsWith("\"")) {
AnnotationType result = getNextAnnotation(); mConsoleOutput.append(line.mid(2,line.length()-3));
mIndex = indexBackup; }
return result; }
void DebugReader::processResult(const QString &result)
{
int pos = result.indexOf('=');
QString name = result.mid(0,pos);
QString value = result.mid(pos+1);
if (name == "bkpt") {
// info about breakpoint
handleBreakpoint(value);
} else if (name == "BreakpointTable") {
// info about breakpoint table
handleBreakpointTable(value);
} else if (name == "stack") {
// info about frame stack
handleFrameStack(value);
} else if (name == "variables") {
// info about local variables & arguments
handleVariables(value);
} else if (name == "frame") {
// info about current selected frame
handleFrame(value);
} else if (name == "asm_insns") {
// info about disassembled codes
handleDisassembled(value);
} else if (name == "value") {
handleEval(value);
} else if (name=="register-names") {
handleRegisterNames(value);
} else if (name == "register-values") {
handleRegisterValues(value);
} else if (name == "memory") {
handleMemory(value);
}
}
void DebugReader::processExecAsyncRecord(const QString &line)
{
if (line.startsWith("*running")) {
mInferiorPaused = false;
return;
}
if (line.startsWith("*stopped")) {
mInferiorPaused = true;
QStringList props = line.split(',');
if (props.count()<2)
return;
QString reason = props[1];
QRegExp exp("^reason=\"(.+)\"$");
reason = exp.cap(1);
if (reason.isEmpty())
return;
if (reason.startsWith("exited")) {
//inferior exited, gdb should terminate too
mProcessExited = true;
return;
}
if (reason==("signal-received")) {
//todo: signal received
return;
}
}
}
void DebugReader::processError(const QString &errorLine)
{
//todo
} }
void DebugReader::processResultRecord(const QString &line) void DebugReader::processResultRecord(const QString &line)
{ {
if (line.startsWith("^exit")) { if (line.startsWith("^exit")) {
doprocessexited = true; mProcessExited = true;
return;
}
if (line.startsWith("^error")) {
processError(line);
return;
}
if (line.startsWith("^done")
|| line.startsWith("^running")) {
int pos = line.indexOf(',');
if (pos>=0) {
QString result = line.mid(pos+1);
processResult(result);
}
return ;
}
if (line.startsWith("^connected")) {
//TODO: connected to remote target
return; return;
} }
} }
void DebugReader::processDebugOutput(const QString& debugOutput) void DebugReader::processDebugOutput(const QString& debugOutput)
@ -1181,6 +1263,8 @@ void DebugReader::processDebugOutput(const QString& debugOutput)
emit parseStarted(); emit parseStarted();
mConsoleOutput.clear();
//try //try
dobacktraceready = false; dobacktraceready = false;
@ -1189,7 +1273,6 @@ void DebugReader::processDebugOutput(const QString& debugOutput)
doevalready = false; doevalready = false;
doupdatememoryview = false; doupdatememoryview = false;
doupdatelocal = false; doupdatelocal = false;
doprocessexited = false;
doupdateexecution = false; doupdateexecution = false;
doreceivedsignal = false; doreceivedsignal = false;
doupdatecpuwindow = false; doupdatecpuwindow = false;
@ -1205,14 +1288,17 @@ void DebugReader::processDebugOutput(const QString& debugOutput)
} }
switch (line[0].unicode()) { switch (line[0].unicode()) {
case '~': // console stream output case '~': // console stream output
processConsoleOutput(line);
break;
case '@': // target stream output case '@': // target stream output
case '&': // log stream output case '&': // log stream output
//todo: process console stream output
break; break;
case '^': // result record case '^': // result record
processResultRecord(line); processResultRecord(line);
break; break;
case '*': // exec async output case '*': // exec async output
processExecAsyncRecord(line);
break;
case '+': // status async output case '+': // status async output
case '=': // notify async output case '=': // notify async output
break; break;
@ -1522,25 +1608,6 @@ void DebugReader::runNextCmd()
} }
} }
void DebugReader::skipSpaces()
{
while (mIndex < mOutput.length() &&
(mOutput[mIndex]=='\t' || mOutput[mIndex]==' '))
mIndex++;
}
void DebugReader::skipToAnnotation()
{
// Walk up to the next annotation
while (mIndex < mOutput.length() &&
(mOutput[mIndex]!=26))
mIndex++;
// Crawl through the remaining ->'s
while (mIndex < mOutput.length() &&
(mOutput[mIndex]==26))
mIndex++;
}
QStringList DebugReader::tokenize(const QString &s) QStringList DebugReader::tokenize(const QString &s)
{ {
QStringList result; QStringList result;
@ -1637,6 +1704,25 @@ QStringList DebugReader::tokenize(const QString &s)
return result; return result;
} }
QString DebugReader::removeToken(const QString &line)
{
int p=0;
while (p<line.length()) {
char ch=line[p];
}
}
bool DebugReader::processExited() const
{
return mProcessExited;
}
bool DebugReader::inferiorPaused() const
{
return mInferiorPaused;
}
bool DebugReader::invalidateAllVars() const bool DebugReader::invalidateAllVars() const
{ {
return mInvalidateAllVars; return mInvalidateAllVars;
@ -1667,10 +1753,17 @@ bool DebugReader::commandRunning()
return !mCmdQueue.isEmpty(); return !mCmdQueue.isEmpty();
} }
bool DebugReader::waitStart()
{
mStartSemaphore.acquire(1);
}
void DebugReader::run() void DebugReader::run()
{ {
mStop = false; mStop = false;
mInferiorPaused = false;
mProcessExited = false;
bool errorOccurred = false; bool errorOccurred = false;
QString cmd = mDebuggerPath; QString cmd = mDebuggerPath;
// QString arguments = "--annotate=2"; // QString arguments = "--annotate=2";
@ -1706,7 +1799,6 @@ void DebugReader::run()
mProcess->start(); mProcess->start();
mProcess->waitForStarted(5000); mProcess->waitForStarted(5000);
mStartSemaphore.release(1); mStartSemaphore.release(1);
while (true) { while (true) {
mProcess->waitForFinished(1); mProcess->waitForFinished(1);
if (mProcess->state()!=QProcess::Running) { if (mProcess->state()!=QProcess::Running) {

View File

@ -18,27 +18,6 @@ enum class DebugCommandSource {
Other Other
}; };
enum class AnnotationType {
TPrePrompt, TPrompt, TPostPrompt,
TSource,
TDisplayBegin, TDisplayEnd,
TDisplayExpression,
TFrameSourceFile, TFrameSourceBegin, TFrameSourceLine, TFrameFunctionName, TFrameWhere,
TFrameArgs,
TFrameBegin, TFrameEnd,
TErrorBegin, TErrorEnd,
TArrayBegin, TArrayEnd,
TElt, TEltRep, TEltRepEnd,
TExit,
TSignal, TSignalName, TSignalNameEnd, TSignalString, TSignalStringEnd,
TValueHistoryValue, TValueHistoryBegin, TValueHistoryEnd,
TArgBegin, TArgEnd, TArgValue, TArgNameEnd,
TFieldBegin, TFieldEnd, TFieldValue, TFieldNameEnd,
TInfoReg, TInfoAsm,
TUnknown, TEOF,
TLocal, TParam, TMemory
};
struct DebugCommand{ struct DebugCommand{
QString command; QString command;
QString params; QString params;
@ -284,10 +263,16 @@ public:
void stopDebug(); void stopDebug();
bool commandRunning(); bool commandRunning();
bool waitStart();
bool invalidateAllVars() const; bool invalidateAllVars() const;
void setInvalidateAllVars(bool invalidateAllVars); void setInvalidateAllVars(bool invalidateAllVars);
bool inferiorPaused() const;
bool processExited() const;
signals: signals:
void parseStarted(); void parseStarted();
void invalidateAllVars(); void invalidateAllVars();
@ -301,15 +286,7 @@ signals:
void cmdFinished(); void cmdFinished();
private: private:
void clearCmdQueue(); void clearCmdQueue();
bool findAnnotation(AnnotationType annotation);
AnnotationType getAnnotation(const QString& s);
AnnotationType getLastAnnotation(const QByteArray& text);
AnnotationType getNextAnnotation();
bool outputTerminated(QByteArray& text); bool outputTerminated(QByteArray& text);
QString getNextFilledLine();
QString getNextLine();
QString getNextWord();
QString getRemainingLine();
void handleDisassembly(); void handleDisassembly();
void handleDisplay(); void handleDisplay();
void handleError(); void handleError();
@ -323,8 +300,11 @@ private:
void handleSignal(); void handleSignal();
void handleSource(); void handleSource();
void handleValueHistoryValue(); void handleValueHistoryValue();
AnnotationType peekNextAnnotation();
void processConsoleOutput(const QString& line);
void processResult(const QString& result);
void processExecAsyncRecord(const QString& line);
void processError(const QString& errorLine);
void processResultRecord(const QString& line); void processResultRecord(const QString& line);
void processDebugOutput(const QString& debugOutput); void processDebugOutput(const QString& debugOutput);
QString processEvalOutput(); QString processEvalOutput();
@ -333,6 +313,7 @@ private:
void skipSpaces(); void skipSpaces();
void skipToAnnotation(); void skipToAnnotation();
QStringList tokenize(const QString& s); QStringList tokenize(const QString& s);
QString removeToken(const QString& line);
private: private:
Debugger *mDebugger; Debugger *mDebugger;
QString mDebuggerPath; QString mDebuggerPath;
@ -365,7 +346,6 @@ private:
bool dodisassemblerready; bool dodisassemblerready;
bool doregistersready; bool doregistersready;
bool doevalready; bool doevalready;
bool doprocessexited;
bool doupdatecpuwindow; bool doupdatecpuwindow;
bool doupdateexecution; bool doupdateexecution;
bool doreceivedsignal; bool doreceivedsignal;
@ -373,9 +353,11 @@ private:
bool doupdatememoryview; bool doupdatememoryview;
bool doupdatelocal; bool doupdatelocal;
bool mStop; bool mInferiorPaused;
bool mProcessExited;
QStringList mConsoleOutput;
friend class Debugger; bool mStop;
// QThread interface // QThread interface
protected: protected:
void run() override; void run() override;

View File

@ -1296,7 +1296,6 @@ void MainWindow::debug()
if (!mDebugger->start()) if (!mDebugger->start())
return; return;
filePath.replace('\\','/'); filePath.replace('\\','/');
mDebugger->sendCommand("-gdb-set","mi-async on");
mDebugger->sendCommand("-gdb-set","host-charset UTF-8"); mDebugger->sendCommand("-gdb-set","host-charset UTF-8");
mDebugger->sendCommand("-file-exec-and-symbols", '"' + filePath + '"'); mDebugger->sendCommand("-file-exec-and-symbols", '"' + filePath + '"');
@ -1376,7 +1375,6 @@ void MainWindow::debug()
mDebugger->setUseUTF8(e->fileEncoding() == ENCODING_UTF8 || e->fileEncoding() == ENCODING_UTF8_BOM); mDebugger->setUseUTF8(e->fileEncoding() == ENCODING_UTF8 || e->fileEncoding() == ENCODING_UTF8_BOM);
if (!mDebugger->start()) if (!mDebugger->start())
return; return;
mDebugger->sendCommand("-gdb-set","mi-async on");
mDebugger->sendCommand("-gdb-set","host-charset UTF-8"); mDebugger->sendCommand("-gdb-set","host-charset UTF-8");
mDebugger->sendCommand("-file-exec-and-symbols", QString("\"%1\"").arg(debugFile.filePath().replace('\\','/'))); mDebugger->sendCommand("-file-exec-and-symbols", QString("\"%1\"").arg(debugFile.filePath().replace('\\','/')));
} }