2021-12-26 23:18:28 +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/>.
|
|
|
|
*/
|
2021-07-03 21:57:50 +08:00
|
|
|
#ifndef DEBUGGER_H
|
|
|
|
#define DEBUGGER_H
|
|
|
|
|
2021-07-17 19:32:23 +08:00
|
|
|
#include <QAbstractTableModel>
|
2021-07-03 21:57:50 +08:00
|
|
|
#include <QList>
|
|
|
|
#include <QList>
|
2021-07-17 19:32:23 +08:00
|
|
|
#include <QMap>
|
2021-07-03 21:57:50 +08:00
|
|
|
#include <QMutex>
|
|
|
|
#include <QObject>
|
2021-07-19 23:02:32 +08:00
|
|
|
#include <QProcess>
|
2021-07-03 21:57:50 +08:00
|
|
|
#include <QQueue>
|
|
|
|
#include <QQueue>
|
2021-07-27 00:14:24 +08:00
|
|
|
#include <QSemaphore>
|
2022-01-11 22:29:03 +08:00
|
|
|
#include <QSet>
|
2021-07-19 23:02:32 +08:00
|
|
|
#include <QThread>
|
2021-12-27 10:59:04 +08:00
|
|
|
#include <QTimer>
|
2021-07-03 21:57:50 +08:00
|
|
|
#include <memory>
|
2021-11-20 07:53:39 +08:00
|
|
|
#include "gdbmiresultparser.h"
|
|
|
|
|
2021-07-03 21:57:50 +08:00
|
|
|
enum class DebugCommandSource {
|
|
|
|
Console,
|
2022-01-01 09:17:12 +08:00
|
|
|
HeartBeat,
|
2021-07-03 21:57:50 +08:00
|
|
|
Other
|
|
|
|
};
|
|
|
|
|
|
|
|
struct DebugCommand{
|
|
|
|
QString command;
|
|
|
|
QString params;
|
|
|
|
DebugCommandSource source;
|
|
|
|
};
|
|
|
|
|
|
|
|
using PDebugCommand = std::shared_ptr<DebugCommand>;
|
2021-07-31 14:04:43 +08:00
|
|
|
struct WatchVar;
|
|
|
|
using PWatchVar = std::shared_ptr<WatchVar>;
|
2021-07-17 19:32:23 +08:00
|
|
|
struct WatchVar {
|
|
|
|
QString name;
|
2021-11-25 11:24:38 +08:00
|
|
|
QString expression;
|
|
|
|
bool hasMore;
|
2021-09-19 09:45:03 +08:00
|
|
|
QString value;
|
2021-11-25 11:24:38 +08:00
|
|
|
QString type;
|
|
|
|
int numChild;
|
2021-07-31 14:04:43 +08:00
|
|
|
QList<PWatchVar> children;
|
2022-10-16 23:10:57 +08:00
|
|
|
std::weak_ptr<WatchVar> parent; //use raw point to prevent circular-reference
|
|
|
|
qint64 timestamp;
|
2021-07-17 19:32:23 +08:00
|
|
|
};
|
|
|
|
|
2022-01-02 10:37:00 +08:00
|
|
|
enum class BreakpointType {
|
|
|
|
Breakpoint,
|
|
|
|
Watchpoint,
|
|
|
|
ReadWatchpoint,
|
|
|
|
WriteWatchpoint
|
|
|
|
};
|
|
|
|
|
2021-07-03 21:57:50 +08:00
|
|
|
struct Breakpoint {
|
2021-11-12 10:51:00 +08:00
|
|
|
int number; // breakpoint number
|
|
|
|
QString type; // type of the breakpoint
|
|
|
|
QString catch_type;
|
2021-07-03 21:57:50 +08:00
|
|
|
int line;
|
2021-07-24 11:18:25 +08:00
|
|
|
QString filename;
|
2021-07-03 21:57:50 +08:00
|
|
|
QString condition;
|
2021-10-21 19:33:11 +08:00
|
|
|
bool enabled;
|
2022-01-02 11:43:23 +08:00
|
|
|
BreakpointType breakpointType;
|
2022-10-16 23:10:57 +08:00
|
|
|
qint64 timestamp;
|
2021-07-03 21:57:50 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
using PBreakpoint = std::shared_ptr<Breakpoint>;
|
|
|
|
|
2022-10-16 23:10:57 +08:00
|
|
|
struct DebugConfig {
|
|
|
|
QList<PBreakpoint> breakpoints;
|
|
|
|
QList<PWatchVar> watchVars;
|
|
|
|
qint64 timestamp;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
using PDebugConfig=std::shared_ptr<DebugConfig>;
|
|
|
|
|
2021-07-03 21:57:50 +08:00
|
|
|
struct Trace {
|
|
|
|
QString funcname;
|
|
|
|
QString filename;
|
2021-11-23 21:08:33 +08:00
|
|
|
QString address;
|
2021-07-03 21:57:50 +08:00
|
|
|
int line;
|
2021-11-23 21:08:33 +08:00
|
|
|
int level;
|
2021-07-03 21:57:50 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
using PTrace = std::shared_ptr<Trace>;
|
|
|
|
|
2021-08-01 23:24:37 +08:00
|
|
|
class RegisterModel: public QAbstractTableModel {
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
explicit RegisterModel(QObject* parent = nullptr);
|
|
|
|
int rowCount(const QModelIndex &parent) const override;
|
|
|
|
int columnCount(const QModelIndex &parent) const override;
|
|
|
|
QVariant data(const QModelIndex &index, int role) const override;
|
|
|
|
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
2021-11-25 09:05:45 +08:00
|
|
|
void updateNames(const QStringList& regNames);
|
|
|
|
void updateValues(const QHash<int,QString> registerValues);
|
2021-08-01 23:24:37 +08:00
|
|
|
void clear();
|
|
|
|
private:
|
2021-11-25 09:05:45 +08:00
|
|
|
QStringList mRegisterNames;
|
|
|
|
QHash<int,QString> mRegisterValues;
|
2021-08-01 23:24:37 +08:00
|
|
|
};
|
|
|
|
|
2022-10-16 23:10:57 +08:00
|
|
|
class Debugger;
|
|
|
|
|
2021-07-17 19:32:23 +08:00
|
|
|
class BreakpointModel: public QAbstractTableModel {
|
2021-07-24 11:18:25 +08:00
|
|
|
Q_OBJECT
|
2021-07-17 19:32:23 +08:00
|
|
|
// QAbstractItemModel interface
|
|
|
|
public:
|
2021-07-24 11:18:25 +08:00
|
|
|
explicit BreakpointModel(QObject *parent = nullptr);
|
2021-07-17 19:32:23 +08:00
|
|
|
int rowCount(const QModelIndex &parent) const override;
|
|
|
|
int columnCount(const QModelIndex &parent) const override;
|
|
|
|
QVariant data(const QModelIndex &index, int role) const override;
|
|
|
|
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
2022-10-16 23:10:57 +08:00
|
|
|
void addBreakpoint(PBreakpoint p, bool forProject);
|
|
|
|
void clear(bool forProject);
|
|
|
|
void removeBreakpoint(int index, bool forProject);
|
|
|
|
PBreakpoint setBreakPointCondition(int index, const QString& condition, bool forProject);
|
|
|
|
const QList<PBreakpoint>& breakpoints(bool forProject) const {
|
|
|
|
return forProject?mProjectBreakpoints:mBreakpoints;
|
|
|
|
}
|
|
|
|
|
|
|
|
PBreakpoint breakpoint(int index, bool forProject) const;
|
|
|
|
|
2021-09-05 22:16:54 +08:00
|
|
|
public slots:
|
2021-11-21 08:38:03 +08:00
|
|
|
void updateBreakpointNumber(const QString& filename, int line, int number);
|
|
|
|
void invalidateAllBreakpointNumbers(); // call this when gdb is stopped
|
2022-10-16 23:10:57 +08:00
|
|
|
void onFileDeleteLines(const QString& filename, int startLine, int count, bool forProject);
|
|
|
|
void onFileInsertLines(const QString& filename, int startLine, int count, bool forProject);
|
|
|
|
private:
|
|
|
|
bool isForProject() const;
|
|
|
|
void setIsForProject(bool newIsForProject);
|
|
|
|
QList<PBreakpoint> loadJson(const QJsonArray& jsonArray, qint64 criteriaTime);
|
|
|
|
QJsonArray toJson(const QString& projectFolder);
|
|
|
|
void setBreakpoints(const QList<PBreakpoint>& list, bool forProject);
|
|
|
|
|
2021-07-17 19:32:23 +08:00
|
|
|
private:
|
2022-10-16 23:10:57 +08:00
|
|
|
QList<PBreakpoint> mBreakpoints;
|
|
|
|
QList<PBreakpoint> mProjectBreakpoints;
|
|
|
|
bool mIsForProject;
|
|
|
|
|
|
|
|
friend class Debugger;
|
2021-07-17 19:32:23 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
class BacktraceModel : public QAbstractTableModel {
|
2021-07-31 14:04:43 +08:00
|
|
|
Q_OBJECT
|
2021-07-17 19:32:23 +08:00
|
|
|
// QAbstractItemModel interface
|
|
|
|
public:
|
2021-07-24 11:18:25 +08:00
|
|
|
explicit BacktraceModel(QObject *parent = nullptr);
|
2021-07-17 19:32:23 +08:00
|
|
|
int rowCount(const QModelIndex &parent) const override;
|
|
|
|
int columnCount(const QModelIndex &parent) const override;
|
|
|
|
QVariant data(const QModelIndex &index, int role) const override;
|
|
|
|
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
|
|
|
void addTrace(PTrace p);
|
|
|
|
void clear();
|
2021-07-24 11:18:25 +08:00
|
|
|
void removeTrace(int index);
|
|
|
|
const QList<PTrace>& backtraces() const;
|
2021-09-05 21:05:38 +08:00
|
|
|
PTrace backtrace(int index) const;
|
2021-07-17 19:32:23 +08:00
|
|
|
private:
|
|
|
|
QList<PTrace> mList;
|
|
|
|
};
|
|
|
|
|
2021-07-31 14:04:43 +08:00
|
|
|
class WatchModel: public QAbstractItemModel {
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
2021-07-31 20:19:45 +08:00
|
|
|
explicit WatchModel(QObject *parent = nullptr);
|
2021-07-31 14:04:43 +08:00
|
|
|
QVariant data(const QModelIndex &index, int role) const override;
|
|
|
|
|
|
|
|
QModelIndex index(int row, int column,
|
|
|
|
const QModelIndex &parent = QModelIndex()) const override;
|
|
|
|
QModelIndex parent(const QModelIndex &index) const override;
|
2021-11-25 20:26:43 +08:00
|
|
|
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
|
|
|
void fetchMore(const QModelIndex &parent) override;
|
|
|
|
bool canFetchMore(const QModelIndex &parent) const override;
|
2021-07-31 14:04:43 +08:00
|
|
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
|
|
|
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
2021-11-25 20:26:43 +08:00
|
|
|
bool hasChildren(const QModelIndex &parent) const override;
|
2022-10-16 23:10:57 +08:00
|
|
|
QModelIndex index(PWatchVar var) const;
|
|
|
|
QModelIndex index(WatchVar* pVar) const;
|
|
|
|
|
2021-11-25 11:24:38 +08:00
|
|
|
void removeWatchVar(const QString& expression);
|
2021-08-31 11:13:12 +08:00
|
|
|
void removeWatchVar(const QModelIndex& index);
|
2021-07-31 14:04:43 +08:00
|
|
|
void clear();
|
2022-10-23 00:39:24 +08:00
|
|
|
void clear(bool forProject);
|
2021-11-25 20:26:43 +08:00
|
|
|
PWatchVar findWatchVar(const QModelIndex& index);
|
|
|
|
PWatchVar findWatchVar(const QString& expr);
|
|
|
|
void resetAllVarInfos();
|
|
|
|
void clearAllVarInfos();
|
2021-09-19 01:58:09 +08:00
|
|
|
void beginUpdate();
|
|
|
|
void endUpdate();
|
2021-07-31 20:19:45 +08:00
|
|
|
void notifyUpdated(PWatchVar var);
|
2022-01-12 17:14:39 +08:00
|
|
|
signals:
|
|
|
|
void setWatchVarValue(const QString& name, const QString& value);
|
2021-11-25 20:26:43 +08:00
|
|
|
public slots:
|
|
|
|
void updateVarInfo(const QString& expression,
|
|
|
|
const QString& name,
|
|
|
|
int numChild,
|
|
|
|
const QString& value,
|
|
|
|
const QString& type,
|
|
|
|
bool hasMore);
|
|
|
|
void prepareVarChildren(const QString& parentName, int numChild, bool hasMore);
|
|
|
|
void addVarChild(const QString& parentName, const QString& name,
|
|
|
|
const QString& exp, int numChild,
|
|
|
|
const QString& value, const QString& type,
|
|
|
|
bool hasMore);
|
|
|
|
void updateVarValue(const QString& name, const QString& val,
|
|
|
|
const QString& inScope, bool typeChanged,
|
|
|
|
const QString& newType, int newNumChildren,
|
|
|
|
bool hasMore);
|
2022-03-30 19:28:46 +08:00
|
|
|
void updateAllHasMoreVars();
|
2021-11-25 20:26:43 +08:00
|
|
|
signals:
|
|
|
|
void fetchChildren(const QString& name);
|
|
|
|
private:
|
2022-10-16 23:10:57 +08:00
|
|
|
bool isForProject() const;
|
|
|
|
void setIsForProject(bool newIsForProject);
|
|
|
|
const QList<PWatchVar> &watchVars(bool forProject) const;
|
|
|
|
QJsonArray toJson(bool forProject);
|
|
|
|
QList<PWatchVar> loadJson(const QJsonArray &jsonArray, qint64 criteriaTimestamp);
|
|
|
|
const QList<PWatchVar> &watchVars() const;
|
2022-10-17 23:23:05 +08:00
|
|
|
void addWatchVar(PWatchVar watchVar, bool forProject);
|
2022-10-16 23:10:57 +08:00
|
|
|
void setWatchVars(const QList<PWatchVar> list, bool forProject);
|
|
|
|
|
2021-07-31 14:04:43 +08:00
|
|
|
private:
|
|
|
|
QList<PWatchVar> mWatchVars;
|
2022-10-16 23:10:57 +08:00
|
|
|
QList<PWatchVar> mProjectWatchVars;
|
|
|
|
|
|
|
|
QHash<QString,PWatchVar> mVarIndex; //var index is only valid for the current debugging session
|
|
|
|
|
2021-09-19 01:58:09 +08:00
|
|
|
int mUpdateCount;
|
2022-10-16 23:10:57 +08:00
|
|
|
bool mIsForProject;
|
2022-01-12 17:14:39 +08:00
|
|
|
|
|
|
|
// QAbstractItemModel interface
|
|
|
|
public:
|
|
|
|
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
|
|
|
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
2022-10-16 23:10:57 +08:00
|
|
|
|
|
|
|
friend class Debugger;
|
2021-07-31 14:04:43 +08:00
|
|
|
};
|
|
|
|
|
2022-01-11 22:29:03 +08:00
|
|
|
struct MemoryLine {
|
|
|
|
uintptr_t startAddress;
|
|
|
|
QList<unsigned char> datas;
|
|
|
|
QSet<int> changedDatas;
|
|
|
|
};
|
|
|
|
|
|
|
|
using PMemoryLine = std::shared_ptr<MemoryLine>;
|
|
|
|
|
|
|
|
class MemoryModel: public QAbstractTableModel{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
explicit MemoryModel(int dataPerLine,QObject* parent=nullptr);
|
|
|
|
|
|
|
|
void updateMemory(const QStringList& value);
|
|
|
|
qulonglong startAddress() const;
|
|
|
|
void reset();
|
|
|
|
// QAbstractItemModel interface
|
|
|
|
signals:
|
|
|
|
void setMemoryData(qlonglong address, unsigned char data);
|
|
|
|
public:
|
|
|
|
int rowCount(const QModelIndex &parent) const override;
|
|
|
|
int columnCount(const QModelIndex &parent) const override;
|
|
|
|
QVariant data(const QModelIndex &index, int role) const override;
|
|
|
|
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
|
|
|
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
|
|
|
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
int mDataPerLine;
|
|
|
|
QList<PMemoryLine> mLines;
|
|
|
|
qulonglong mStartAddress;
|
|
|
|
};
|
|
|
|
|
2021-07-17 19:32:23 +08:00
|
|
|
|
2021-07-03 21:57:50 +08:00
|
|
|
class DebugReader;
|
2021-12-25 18:09:50 +08:00
|
|
|
class DebugTarget;
|
2021-07-24 11:18:25 +08:00
|
|
|
class Editor;
|
|
|
|
|
|
|
|
using PDebugReader = std::shared_ptr<DebugReader>;
|
2021-07-03 21:57:50 +08:00
|
|
|
|
|
|
|
class Debugger : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
explicit Debugger(QObject *parent = nullptr);
|
2022-10-10 18:05:18 +08:00
|
|
|
~Debugger();
|
2021-07-24 11:18:25 +08:00
|
|
|
// Play/pause
|
2022-06-16 21:34:31 +08:00
|
|
|
bool start(int compilerSetIndex, const QString& inferior, const QStringList& binDirs);
|
2021-07-24 11:18:25 +08:00
|
|
|
void sendCommand(const QString& command, const QString& params,
|
|
|
|
DebugCommandSource source = DebugCommandSource::Other);
|
2021-08-29 22:08:43 +08:00
|
|
|
bool commandRunning();
|
2021-11-24 21:22:01 +08:00
|
|
|
bool inferiorRunning();
|
2021-12-27 10:59:04 +08:00
|
|
|
void interrupt();
|
2021-07-24 11:18:25 +08:00
|
|
|
|
2022-10-16 23:10:57 +08:00
|
|
|
bool isForProject() const;
|
|
|
|
void setIsForProject(bool newIsForProject);
|
2022-10-23 00:39:24 +08:00
|
|
|
void clearForProject();
|
2022-10-16 23:10:57 +08:00
|
|
|
|
2021-07-26 18:22:09 +08:00
|
|
|
//breakpoints
|
2021-07-24 11:18:25 +08:00
|
|
|
void addBreakpoint(int line, const Editor* editor);
|
2022-10-16 23:10:57 +08:00
|
|
|
void addBreakpoint(int line, const QString& filename, bool forProject);
|
|
|
|
void deleteBreakpoints(const QString& filename, bool forProject);
|
2021-07-24 11:18:25 +08:00
|
|
|
void deleteBreakpoints(const Editor* editor);
|
2022-10-16 23:10:57 +08:00
|
|
|
void deleteBreakpoints(bool forProject);
|
2021-07-24 11:18:25 +08:00
|
|
|
void removeBreakpoint(int line, const Editor* editor);
|
2022-10-16 23:10:57 +08:00
|
|
|
void removeBreakpoint(int line, const QString& filename, bool forProject);
|
|
|
|
void removeBreakpoint(int index, bool forProject);
|
|
|
|
PBreakpoint breakpointAt(int line, const QString &filename, int *index, bool forProject);
|
|
|
|
PBreakpoint breakpointAt(int line, const Editor *editor, int *index);
|
|
|
|
void setBreakPointCondition(int index, const QString& condition, bool forProject);
|
2021-07-25 13:03:46 +08:00
|
|
|
void sendAllBreakpointsToDebugger();
|
2021-07-31 20:19:45 +08:00
|
|
|
|
2022-10-16 23:10:57 +08:00
|
|
|
void saveForNonproject(const QString &filename);
|
|
|
|
void saveForProject(const QString &filename, const QString &projectFolder);
|
|
|
|
|
|
|
|
void loadForNonproject(const QString &filename);
|
|
|
|
void loadForProject(const QString& filename, const QString& projectFolder);
|
|
|
|
|
2021-07-26 18:22:09 +08:00
|
|
|
//watch vars
|
2021-11-25 20:26:43 +08:00
|
|
|
void addWatchVar(const QString& expression);
|
|
|
|
void modifyWatchVarExpression(const QString& oldExpr, const QString& newExpr);
|
2021-07-26 18:22:09 +08:00
|
|
|
|
2021-08-31 11:13:12 +08:00
|
|
|
void removeWatchVars(bool deleteparent);
|
|
|
|
void removeWatchVar(const QModelIndex& index);
|
2021-11-25 20:26:43 +08:00
|
|
|
void sendAllWatchVarsToDebugger();
|
|
|
|
PWatchVar findWatchVar(const QString& expression);
|
2022-05-30 16:40:45 +08:00
|
|
|
PWatchVar watchVarAt(const QModelIndex& index);
|
2021-09-19 02:00:25 +08:00
|
|
|
// void notifyWatchVarUpdated(PWatchVar var);
|
2021-07-26 18:22:09 +08:00
|
|
|
|
2022-10-16 23:10:57 +08:00
|
|
|
std::shared_ptr<BacktraceModel> backtraceModel();
|
|
|
|
std::shared_ptr<BreakpointModel> breakpointModel();
|
2021-07-26 11:47:54 +08:00
|
|
|
bool executing() const;
|
|
|
|
|
2021-07-26 18:22:09 +08:00
|
|
|
int leftPageIndexBackup() const;
|
|
|
|
void setLeftPageIndexBackup(int leftPageIndexBackup);
|
|
|
|
|
2022-10-16 23:10:57 +08:00
|
|
|
std::shared_ptr<WatchModel> watchModel() const;
|
2021-08-01 01:06:43 +08:00
|
|
|
|
2022-10-16 23:10:57 +08:00
|
|
|
std::shared_ptr<RegisterModel> registerModel() const;
|
2021-08-01 23:24:37 +08:00
|
|
|
|
2022-10-16 23:10:57 +08:00
|
|
|
std::shared_ptr<MemoryModel> memoryModel() const;
|
2022-01-11 22:29:03 +08:00
|
|
|
|
2022-05-15 17:14:22 +08:00
|
|
|
bool forceUTF8() const;
|
|
|
|
void setForceUTF8(bool newForceUTF8);
|
|
|
|
|
2021-08-29 22:08:43 +08:00
|
|
|
signals:
|
|
|
|
void evalValueReady(const QString& s);
|
2021-09-29 22:55:53 +08:00
|
|
|
void memoryExamineReady(const QStringList& s);
|
|
|
|
void localsReady(const QStringList& s);
|
2021-07-26 00:22:08 +08:00
|
|
|
public slots:
|
|
|
|
void stop();
|
2022-01-11 22:29:03 +08:00
|
|
|
void refreshAll();
|
2021-07-24 11:18:25 +08:00
|
|
|
|
|
|
|
private:
|
2021-07-31 20:19:45 +08:00
|
|
|
void sendWatchCommand(PWatchVar var);
|
|
|
|
void sendRemoveWatchCommand(PWatchVar var);
|
2021-07-25 13:03:46 +08:00
|
|
|
void sendBreakpointCommand(PBreakpoint breakpoint);
|
2022-10-16 23:10:57 +08:00
|
|
|
void sendClearBreakpointCommand(int index, bool forProject);
|
2021-07-25 13:03:46 +08:00
|
|
|
void sendClearBreakpointCommand(PBreakpoint breakpoint);
|
2022-10-16 23:10:57 +08:00
|
|
|
void save(const QString& filename, const QString& projectFolder);
|
|
|
|
PDebugConfig load(const QString& filename, bool forProject);
|
2022-10-17 23:23:05 +08:00
|
|
|
void addWatchVar(const PWatchVar &watchVar, bool forProject);
|
2021-08-01 01:06:43 +08:00
|
|
|
|
2021-07-26 11:47:54 +08:00
|
|
|
private slots:
|
|
|
|
void syncFinishedParsing();
|
2022-01-11 22:29:03 +08:00
|
|
|
void setMemoryData(qulonglong address, unsigned char data);
|
2022-01-12 17:14:39 +08:00
|
|
|
void setWatchVarValue(const QString& name, const QString& value);
|
2021-11-25 07:42:56 +08:00
|
|
|
void updateMemory(const QStringList& value);
|
|
|
|
void updateEval(const QString& value);
|
|
|
|
void updateDisassembly(const QString& file, const QString& func,const QStringList& value);
|
2021-07-30 23:28:58 +08:00
|
|
|
void onChangeDebugConsoleLastline(const QString& text);
|
2021-12-25 19:22:29 +08:00
|
|
|
void cleanUpReader();
|
2021-11-25 09:05:45 +08:00
|
|
|
void updateRegisterNames(const QStringList& registerNames);
|
|
|
|
void updateRegisterValues(const QHash<int,QString>& values);
|
2021-11-25 20:26:43 +08:00
|
|
|
void refreshWatchVars();
|
|
|
|
void fetchVarChildren(const QString& varName);
|
2021-07-03 21:57:50 +08:00
|
|
|
private:
|
|
|
|
bool mExecuting;
|
|
|
|
bool mCommandChanged;
|
2022-10-16 23:10:57 +08:00
|
|
|
std::shared_ptr<BreakpointModel> mBreakpointModel;
|
|
|
|
std::shared_ptr<BacktraceModel> mBacktraceModel;
|
|
|
|
std::shared_ptr<WatchModel> mWatchModel;
|
|
|
|
std::shared_ptr<RegisterModel> mRegisterModel;
|
|
|
|
std::shared_ptr<MemoryModel> mMemoryModel;
|
2021-08-01 23:24:37 +08:00
|
|
|
DebugReader *mReader;
|
2021-12-25 18:09:50 +08:00
|
|
|
DebugTarget *mTarget;
|
2022-05-15 17:14:22 +08:00
|
|
|
bool mForceUTF8;
|
2021-07-26 18:22:09 +08:00
|
|
|
int mLeftPageIndexBackup;
|
2022-10-16 23:10:57 +08:00
|
|
|
qint64 mLastLoadtime;
|
|
|
|
qint64 mProjectLastLoadtime;
|
2021-07-03 21:57:50 +08:00
|
|
|
};
|
|
|
|
|
2021-12-25 18:09:50 +08:00
|
|
|
class DebugTarget: public QThread {
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
explicit DebugTarget(const QString& inferior,
|
|
|
|
const QString& GDBServer,
|
|
|
|
int port,
|
|
|
|
QObject *parent = nullptr);
|
2022-01-12 18:47:50 +08:00
|
|
|
void setInputFile(const QString& inputFile);
|
2021-12-25 18:09:50 +08:00
|
|
|
void stopDebug();
|
|
|
|
void waitStart();
|
2022-06-16 21:56:07 +08:00
|
|
|
const QStringList &binDirs() const;
|
|
|
|
void addBinDirs(const QStringList &binDirs);
|
|
|
|
void addBinDir(const QString &binDir);
|
2021-12-25 18:09:50 +08:00
|
|
|
signals:
|
|
|
|
void processError(QProcess::ProcessError error);
|
|
|
|
private:
|
|
|
|
QString mInferior;
|
|
|
|
QString mGDBServer;
|
|
|
|
int mPort;
|
|
|
|
bool mStop;
|
|
|
|
std::shared_ptr<QProcess> mProcess;
|
|
|
|
QSemaphore mStartSemaphore;
|
2021-12-25 20:02:53 +08:00
|
|
|
bool mErrorOccured;
|
2022-01-12 18:47:50 +08:00
|
|
|
QString mInputFile;
|
2022-06-16 21:56:07 +08:00
|
|
|
QStringList mBinDirs;
|
2021-12-25 18:09:50 +08:00
|
|
|
|
|
|
|
// QThread interface
|
|
|
|
protected:
|
|
|
|
void run() override;
|
|
|
|
};
|
|
|
|
|
2021-07-19 23:02:32 +08:00
|
|
|
class DebugReader : public QThread
|
2021-07-03 21:57:50 +08:00
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
2021-07-25 00:26:13 +08:00
|
|
|
explicit DebugReader(Debugger* debugger, QObject *parent = nullptr);
|
2021-11-24 17:53:25 +08:00
|
|
|
void postCommand(const QString &Command, const QString &Params, DebugCommandSource Source);
|
|
|
|
void registerInferiorStoppedCommand(const QString &Command, const QString &Params);
|
2021-07-25 00:26:13 +08:00
|
|
|
QString debuggerPath() const;
|
|
|
|
void setDebuggerPath(const QString &debuggerPath);
|
|
|
|
void stopDebug();
|
|
|
|
|
2021-08-29 22:08:43 +08:00
|
|
|
bool commandRunning();
|
2021-11-24 17:53:25 +08:00
|
|
|
void waitStart();
|
2021-08-29 22:08:43 +08:00
|
|
|
|
2021-11-10 17:05:37 +08:00
|
|
|
bool inferiorPaused() const;
|
|
|
|
|
|
|
|
bool processExited() const;
|
|
|
|
|
2021-11-23 21:08:33 +08:00
|
|
|
bool signalReceived() const;
|
|
|
|
|
|
|
|
const QStringList &consoleOutput() const;
|
|
|
|
|
|
|
|
int breakPointLine() const;
|
|
|
|
|
|
|
|
const QString &breakPointFile() const;
|
|
|
|
|
|
|
|
const PDebugCommand ¤tCmd() 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;
|
2021-11-10 17:05:37 +08:00
|
|
|
|
2021-11-24 10:07:35 +08:00
|
|
|
bool receivedSFWarning() const;
|
|
|
|
|
2021-11-24 17:53:25 +08:00
|
|
|
const QStringList &fullOutput() const;
|
|
|
|
|
2021-11-24 21:22:01 +08:00
|
|
|
bool inferiorRunning() const;
|
|
|
|
|
2021-11-25 09:05:45 +08:00
|
|
|
const QString &signalName() const;
|
|
|
|
|
|
|
|
const QString &signalMeaning() const;
|
|
|
|
|
2022-06-16 21:34:31 +08:00
|
|
|
const QStringList &binDirs() const;
|
|
|
|
void addBinDirs(const QStringList &binDirs);
|
|
|
|
void addBinDir(const QString &binDir);
|
|
|
|
|
2021-07-18 08:52:53 +08:00
|
|
|
signals:
|
|
|
|
void parseStarted();
|
|
|
|
void invalidateAllVars();
|
|
|
|
void parseFinished();
|
2021-07-19 23:02:32 +08:00
|
|
|
void writeToDebugFailed();
|
|
|
|
void processError(QProcess::ProcessError error);
|
2021-08-01 10:00:27 +08:00
|
|
|
void changeDebugConsoleLastLine(const QString& text);
|
2021-09-19 14:28:30 +08:00
|
|
|
void cmdStarted();
|
|
|
|
void cmdFinished();
|
2021-11-21 08:38:03 +08:00
|
|
|
|
|
|
|
void breakpointInfoGetted(const QString& filename, int line, int number);
|
2021-11-24 10:07:35 +08:00
|
|
|
void inferiorContinued();
|
2021-11-24 17:53:25 +08:00
|
|
|
void inferiorStopped(const QString& filename, int line, bool setFocus);
|
2021-11-24 10:07:35 +08:00
|
|
|
void localsUpdated(const QStringList& localsValue);
|
|
|
|
void evalUpdated(const QString& value);
|
|
|
|
void memoryUpdated(const QStringList& memoryValues);
|
2021-11-25 07:42:56 +08:00
|
|
|
void disassemblyUpdate(const QString& filename, const QString& funcName, const QStringList& result);
|
2021-11-25 09:05:45 +08:00
|
|
|
void registerNamesUpdated(const QStringList& registerNames);
|
|
|
|
void registerValuesUpdated(const QHash<int,QString>& values);
|
2021-11-25 20:26:43 +08:00
|
|
|
void varCreated(const QString& expression,
|
|
|
|
const QString& name,
|
|
|
|
int numChild,
|
|
|
|
const QString& value,
|
|
|
|
const QString& type,
|
|
|
|
bool hasMore);
|
|
|
|
void prepareVarChildren(const QString& parentName,int numChild, bool hasMore);
|
|
|
|
void addVarChild(const QString& parentName, const QString& name,
|
|
|
|
const QString& exp, int numChild,
|
|
|
|
const QString& value, const QString& type,
|
|
|
|
bool hasMore);
|
|
|
|
void varValueUpdated(const QString& name, const QString& val,
|
|
|
|
const QString& inScope, bool typeChanged,
|
|
|
|
const QString& newType, int newNumChildren,
|
|
|
|
bool hasMore);
|
2022-03-30 19:28:46 +08:00
|
|
|
void varsValueUpdated();
|
2022-06-16 21:34:31 +08:00
|
|
|
|
2021-07-03 21:57:50 +08:00
|
|
|
private:
|
|
|
|
void clearCmdQueue();
|
2021-11-12 10:51:00 +08:00
|
|
|
|
2021-07-19 23:02:32 +08:00
|
|
|
void runNextCmd();
|
2021-09-19 09:45:03 +08:00
|
|
|
QStringList tokenize(const QString& s);
|
2021-11-12 10:51:00 +08:00
|
|
|
|
2021-11-24 17:53:25 +08:00
|
|
|
bool outputTerminated(const QByteArray& text);
|
2021-11-20 07:53:39 +08:00
|
|
|
void handleBreakpoint(const GDBMIResultParser::ParseObject& breakpoint);
|
2021-11-23 21:08:33 +08:00
|
|
|
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);
|
2021-11-25 09:05:45 +08:00
|
|
|
void handleRegisterNames(const QList<GDBMIResultParser::ParseValue> & names);
|
|
|
|
void handleRegisterValue(const QList<GDBMIResultParser::ParseValue> & values);
|
2021-11-25 20:26:43 +08:00
|
|
|
void handleCreateVar(const GDBMIResultParser::ParseObject& multiVars);
|
|
|
|
void handleListVarChildren(const GDBMIResultParser::ParseObject& multiVars);
|
|
|
|
void handleUpdateVarValue(const QList<GDBMIResultParser::ParseValue> &changes);
|
2021-11-12 10:51:00 +08:00
|
|
|
void processConsoleOutput(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);
|
2021-11-24 17:53:25 +08:00
|
|
|
void runInferiorStoppedHook();
|
2021-11-12 10:51:00 +08:00
|
|
|
QByteArray removeToken(const QByteArray& line);
|
2021-12-27 21:32:30 +08:00
|
|
|
private slots:
|
|
|
|
void asyncUpdate();
|
2021-07-03 21:57:50 +08:00
|
|
|
private:
|
2021-08-01 23:24:37 +08:00
|
|
|
Debugger *mDebugger;
|
2021-07-25 00:26:13 +08:00
|
|
|
QString mDebuggerPath;
|
2022-01-04 16:50:54 +08:00
|
|
|
QMutex mCmdQueueMutex;
|
2021-07-27 00:14:24 +08:00
|
|
|
QSemaphore mStartSemaphore;
|
2021-07-03 21:57:50 +08:00
|
|
|
QQueue<PDebugCommand> mCmdQueue;
|
2021-12-25 20:02:53 +08:00
|
|
|
bool mErrorOccured;
|
2021-12-27 21:32:30 +08:00
|
|
|
bool mAsyncUpdated;
|
2021-07-03 21:57:50 +08:00
|
|
|
//fOnInvalidateAllVars: TInvalidateAllVarsEvent;
|
|
|
|
bool mCmdRunning;
|
|
|
|
PDebugCommand mCurrentCmd;
|
2021-12-25 18:09:50 +08:00
|
|
|
std::shared_ptr<QProcess> mProcess;
|
2022-06-16 21:34:31 +08:00
|
|
|
QStringList mBinDirs;
|
2021-07-19 23:02:32 +08:00
|
|
|
|
2021-07-03 21:57:50 +08:00
|
|
|
//fWatchView: TTreeView;
|
2021-11-23 21:08:33 +08:00
|
|
|
|
2021-11-25 09:05:45 +08:00
|
|
|
QString mSignalName;
|
|
|
|
QString mSignalMeaning;
|
2021-07-03 21:57:50 +08:00
|
|
|
|
2021-11-20 07:53:39 +08:00
|
|
|
//
|
2021-11-24 17:53:25 +08:00
|
|
|
QList<PDebugCommand> mInferiorStoppedHookCommands;
|
2021-11-24 10:07:35 +08:00
|
|
|
bool mInferiorRunning;
|
2021-11-10 17:05:37 +08:00
|
|
|
bool mProcessExited;
|
2021-11-23 21:08:33 +08:00
|
|
|
|
|
|
|
bool mSignalReceived;
|
|
|
|
bool mUpdateCPUInfo;
|
2021-11-24 10:07:35 +08:00
|
|
|
bool mReceivedSFWarning;
|
2021-11-23 21:08:33 +08:00
|
|
|
|
2021-11-24 17:53:25 +08:00
|
|
|
int mCurrentLine;
|
|
|
|
int mCurrentAddress;
|
2021-11-25 07:42:56 +08:00
|
|
|
QString mCurrentFunc;
|
2021-11-24 17:53:25 +08:00
|
|
|
QString mCurrentFile;
|
2021-11-10 17:05:37 +08:00
|
|
|
QStringList mConsoleOutput;
|
2021-11-24 17:53:25 +08:00
|
|
|
QStringList mFullOutput;
|
2021-11-10 17:05:37 +08:00
|
|
|
bool mStop;
|
2021-07-19 23:02:32 +08:00
|
|
|
// QThread interface
|
|
|
|
protected:
|
|
|
|
void run() override;
|
2021-07-03 21:57:50 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif // DEBUGGER_H
|