work save
This commit is contained in:
parent
71f5a7c056
commit
bfd64312d9
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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('\\','/')));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue