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-09 23:08:23 +08:00
|
|
|
struct DebugCommand{
|
|
|
|
QString command;
|
|
|
|
QString params;
|
|
|
|
DebugCommandSource source;
|
|
|
|
};
|
|
|
|
|
|
|
|
using PDebugCommand = std::shared_ptr<DebugCommand>;
|
|
|
|
|
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 09:56:20 +08:00
|
|
|
void postCommand(const QString &Command, const QString &Params, DebugCommandSource Source = DebugCommandSource::Other) override;
|
2024-03-08 22:06:10 +08:00
|
|
|
void registerInferiorStoppedCommand(const QString &Command, const QString &Params) override;
|
|
|
|
void stopDebug() override;
|
2024-03-10 09:56:20 +08:00
|
|
|
DebuggerType clientType() override;
|
2024-03-09 23:08:23 +08:00
|
|
|
const PDebugCommand ¤tCmd() const;
|
|
|
|
|
|
|
|
void interrupt() override;
|
|
|
|
void refreshStackVariables() override;
|
2024-03-10 09:56:20 +08:00
|
|
|
|
2024-03-09 23:08:23 +08:00
|
|
|
void readMemory(qulonglong 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;
|
|
|
|
|
|
|
|
void refreshFrame();
|
|
|
|
void refreshRegisters();
|
|
|
|
void disassembleCurrentFrame(bool blendMode);
|
2024-03-08 22:06:10 +08:00
|
|
|
// QThread interface
|
|
|
|
protected:
|
|
|
|
void run() override;
|
2024-03-09 11:34:52 +08:00
|
|
|
void runNextCmd() override;
|
|
|
|
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);
|
|
|
|
void handleRegisterNames(const QList<GDBMIResultParser::ParseValue> & names);
|
|
|
|
void handleRegisterValue(const QList<GDBMIResultParser::ParseValue> & values);
|
|
|
|
void handleListVarChildren(const GDBMIResultParser::ParseObject& multiVars);
|
|
|
|
void handleUpdateVarValue(const QList<GDBMIResultParser::ParseValue> &changes);
|
|
|
|
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-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
|
|
|
|
|
|
|
QQueue<PDebugCommand> mCmdQueue;
|
|
|
|
PDebugCommand mCurrentCmd;
|
|
|
|
QList<PDebugCommand> mInferiorStoppedHookCommands;
|
|
|
|
|
2024-03-10 09:56:20 +08:00
|
|
|
DebuggerType mClientType;
|
2024-03-08 22:06:10 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif // GDBMI_DEBUGGER_H
|