2024-03-08 22:06:10 +08:00
|
|
|
/*
|
|
|
|
* 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>
|
2024-03-09 11:34:52 +08:00
|
|
|
#include <QByteArray>
|
|
|
|
#include <QList>
|
|
|
|
#include <QMap>
|
|
|
|
#include <QString>
|
|
|
|
#include <QStringList>
|
2024-03-08 22:06:10 +08:00
|
|
|
#include <memory>
|
2024-03-09 11:34:52 +08:00
|
|
|
#include <QRegularExpression>
|
2024-03-08 22:06:10 +08:00
|
|
|
|
2024-03-14 11:21:42 +08:00
|
|
|
struct GDBMICommand{
|
2024-03-09 23:08:23 +08:00
|
|
|
QString command;
|
|
|
|
QString params;
|
|
|
|
DebugCommandSource source;
|
|
|
|
};
|
|
|
|
|
2024-03-14 11:21:42 +08:00
|
|
|
using PGDBMICommand = std::shared_ptr<GDBMICommand>;
|
2024-03-09 23:08:23 +08:00
|
|
|
|
2024-03-08 22:06:10 +08:00
|
|
|
class GDBMIDebuggerClient: public DebuggerClient {
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
2024-03-10 09:56:20 +08:00
|
|
|
explicit GDBMIDebuggerClient(Debugger* debugger, DebuggerType clientType, QObject *parent = nullptr);
|
2024-03-08 22:06:10 +08:00
|
|
|
|
|
|
|
// DebuggerClient interface
|
|
|
|
public:
|
2024-03-10 21:25:24 +08:00
|
|
|
void postCommand(const QString &command, const QString ¶ms, DebugCommandSource source = DebugCommandSource::Other);
|
|
|
|
|
2024-03-08 22:06:10 +08:00
|
|
|
void stopDebug() override;
|
2024-03-10 09:56:20 +08:00
|
|
|
DebuggerType clientType() override;
|
2024-03-14 11:21:42 +08:00
|
|
|
const PGDBMICommand ¤tCmd() const;
|
2024-03-10 21:25:24 +08:00
|
|
|
bool commandRunning() override;
|
|
|
|
|
|
|
|
void initialize(const QString& inferior, bool hasSymbols) override;
|
|
|
|
void runInferior(bool hasBreakpoints) override;
|
2024-03-09 23:08:23 +08:00
|
|
|
|
2024-03-10 11:15:10 +08:00
|
|
|
void stepOver() override;
|
|
|
|
void stepInto() override;
|
|
|
|
void stepOut() override;
|
|
|
|
void runTo(const QString& filename, int line) override;
|
|
|
|
void resume() override;
|
|
|
|
void stepOverInstruction() override;
|
|
|
|
void stepIntoInstruction() override;
|
2024-03-09 23:08:23 +08:00
|
|
|
void interrupt() override;
|
2024-03-10 11:15:10 +08:00
|
|
|
|
2024-03-09 23:08:23 +08:00
|
|
|
void refreshStackVariables() override;
|
2024-03-10 09:56:20 +08:00
|
|
|
|
2024-03-10 11:15:10 +08:00
|
|
|
void readMemory(const QString& startAddress, int rows, int cols) override;
|
2024-03-10 09:56:20 +08:00
|
|
|
void writeMemory(qulonglong address, unsigned char data) override;
|
|
|
|
|
|
|
|
void addBreakpoint(PBreakpoint breakpoint) override;
|
|
|
|
void removeBreakpoint(PBreakpoint breakpoint) override;
|
2024-03-09 23:08:23 +08:00
|
|
|
void addWatchpoint(const QString& watchExp) override;
|
2024-03-10 09:56:20 +08:00
|
|
|
void setBreakpointCondition(PBreakpoint breakpoint) override;
|
|
|
|
|
|
|
|
void addWatch(const QString& expression) override;
|
|
|
|
void removeWatch(PWatchVar watchVar) override;
|
|
|
|
void writeWatchVar(const QString& varName, const QString& value) override;
|
|
|
|
void refreshWatch(PWatchVar var) override;
|
|
|
|
void refreshWatch() override;
|
|
|
|
void fetchWatchVarChildren(const QString& varName) override;
|
|
|
|
|
|
|
|
void evalExpression(const QString& expression) override;
|
|
|
|
|
2024-03-10 21:25:24 +08:00
|
|
|
void selectFrame(PTrace trace) override;
|
2024-03-10 11:15:10 +08:00
|
|
|
void refreshFrame() override;
|
|
|
|
void refreshRegisters() override;
|
|
|
|
void disassembleCurrentFrame(bool blendMode) override;
|
|
|
|
void setDisassemblyLanguage(bool isIntel) override;
|
2024-03-10 21:25:24 +08:00
|
|
|
|
|
|
|
|
|
|
|
void skipDirectoriesInSymbolSearch(const QStringList& lst) override;
|
|
|
|
void addSymbolSearchDirectories(const QStringList& lst) override;
|
2024-03-08 22:06:10 +08:00
|
|
|
// QThread interface
|
|
|
|
protected:
|
|
|
|
void run() override;
|
2024-03-10 21:25:24 +08:00
|
|
|
void runNextCmd();
|
2024-03-09 11:34:52 +08:00
|
|
|
private:
|
|
|
|
QStringList tokenize(const QString& s) const;
|
|
|
|
bool outputTerminated(const QByteArray& text) const;
|
|
|
|
void handleBreakpoint(const GDBMIResultParser::ParseObject& breakpoint);
|
|
|
|
void handleCreateVar(const GDBMIResultParser::ParseObject &multiVars);
|
|
|
|
void handleFrame(const GDBMIResultParser::ParseValue &frame);
|
|
|
|
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);
|
2024-03-11 13:13:53 +08:00
|
|
|
void handleMemoryBytes(const QList<GDBMIResultParser::ParseValue> & rows);
|
2024-03-09 11:34:52 +08:00
|
|
|
void handleRegisterNames(const QList<GDBMIResultParser::ParseValue> & names);
|
2024-03-31 09:36:37 +08:00
|
|
|
void handleRegisterValue(const QList<GDBMIResultParser::ParseValue> & values, bool hexValue);
|
2024-03-09 11:34:52 +08:00
|
|
|
void handleListVarChildren(const GDBMIResultParser::ParseObject& multiVars);
|
|
|
|
void handleUpdateVarValue(const QList<GDBMIResultParser::ParseValue> &changes);
|
2024-03-11 17:28:18 +08:00
|
|
|
void handleDisassembly(const QList<GDBMIResultParser::ParseValue> &instructions);
|
2024-03-09 11:34:52 +08:00
|
|
|
void processConsoleOutput(const QByteArray& line);
|
|
|
|
void processLogOutput(const QByteArray& line);
|
|
|
|
void processResult(const QByteArray& result);
|
|
|
|
void processExecAsyncRecord(const QByteArray& line);
|
|
|
|
void processError(const QByteArray& errorLine);
|
|
|
|
void processResultRecord(const QByteArray& line);
|
|
|
|
void processDebugOutput(const QByteArray& debugOutput);
|
|
|
|
QByteArray removeToken(const QByteArray& line) const;
|
2024-03-09 23:08:23 +08:00
|
|
|
void runInferiorStoppedHook();
|
|
|
|
void clearCmdQueue();
|
2024-03-10 21:25:24 +08:00
|
|
|
void registerInferiorStoppedCommand(const QString &command, const QString ¶ms);
|
2024-03-09 11:34:52 +08:00
|
|
|
private slots:
|
|
|
|
void asyncUpdate();
|
2024-03-08 22:06:10 +08:00
|
|
|
private:
|
|
|
|
bool mStop;
|
|
|
|
std::shared_ptr<QProcess> mProcess;
|
2024-03-09 11:34:52 +08:00
|
|
|
QMap<QString,QStringList> mFileCache;
|
|
|
|
int mCurrentLine;
|
|
|
|
qulonglong mCurrentAddress;
|
|
|
|
QString mCurrentFunc;
|
|
|
|
QString mCurrentFile;
|
|
|
|
|
|
|
|
bool mAsyncUpdated;
|
|
|
|
|
|
|
|
static const QRegularExpression REGdbSourceLine;
|
2024-03-09 23:08:23 +08:00
|
|
|
|
2024-03-14 11:21:42 +08:00
|
|
|
QQueue<PGDBMICommand> mCmdQueue;
|
|
|
|
PGDBMICommand mCurrentCmd;
|
|
|
|
PGDBMICommand mLastConsoleCmd;
|
|
|
|
QList<PGDBMICommand> mInferiorStoppedHookCommands;
|
2024-03-09 23:08:23 +08:00
|
|
|
|
2024-03-10 09:56:20 +08:00
|
|
|
DebuggerType mClientType;
|
2024-03-08 22:06:10 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif // GDBMI_DEBUGGER_H
|