aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/debugger/breakhandler.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/debugger/breakhandler.h')
-rw-r--r--src/plugins/debugger/breakhandler.h367
1 files changed, 230 insertions, 137 deletions
diff --git a/src/plugins/debugger/breakhandler.h b/src/plugins/debugger/breakhandler.h
index 09461ba081..91a47649b1 100644
--- a/src/plugins/debugger/breakhandler.h
+++ b/src/plugins/debugger/breakhandler.h
@@ -28,6 +28,7 @@
#include "breakpoint.h"
#include "debuggerprotocol.h"
+#include <utils/fileutils.h>
#include <utils/treemodel.h>
#include <QCoreApplication>
@@ -38,203 +39,295 @@ namespace Utils { class ItemViewEvent; }
namespace Debugger {
namespace Internal {
-class LocationItem;
class BreakpointItem;
+class BreakpointMarker;
class BreakHandler;
class DebuggerCommand;
class DebuggerEngine;
+class BreakpointManager;
+class GlobalBreakpointMarker;
-// Non-owning "deletion-safe" wrapper around a BreakpointItem *
-class Breakpoint
+class SubBreakpointItem : public QObject, public Utils::TypedTreeItem<Utils::TreeItem, BreakpointItem>
+{
+public:
+ QVariant data(int column, int role) const final;
+
+ BreakpointItem *breakpoint() const { return Utils::TypedTreeItem<Utils::TreeItem, BreakpointItem>::parent(); }
+ void setParameters(const BreakpointParameters &pars) { params = pars; }
+ BreakpointParameters params;
+ QString responseId; //!< Breakpoint number assigned by the debugger engine.
+ QString displayName; //!< Breakpoint number assigned by the debugger engine.
+};
+
+using SubBreakpoint = QPointer<SubBreakpointItem>;
+
+class GlobalBreakpointItem : public QObject, public Utils::TreeItem
{
Q_DECLARE_TR_FUNCTIONS(Debugger::Internal::BreakHandler)
public:
- Breakpoint() = default;
+ explicit GlobalBreakpointItem();
+ ~GlobalBreakpointItem() override;
+
+ QVariant data(int column, int role) const override;
+ QIcon icon() const;
- bool isValid() const;
- operator const void *() const { return isValid() ? this : nullptr; }
- bool operator!() const { return !isValid(); }
+ void deleteBreakpoint();
+ void removeBreakpointFromModel();
- uint hash() const;
+ void updateLineNumber(int lineNumber);
+ void updateFileName(const Utils::FileName &fileName);
- const BreakpointParameters &parameters() const;
- void addToCommand(DebuggerCommand *cmd) const;
+ bool isLocatedAt(const QString &fileName, int lineNumber, bool useMarkerPosition) const;
+
+ QString displayName() const;
+ QString markerFileName() const;
+ QString toolTip() const;
+ int markerLineNumber() const;
+ int modelId() const;
+
+ bool isEnabled() const { return m_params.enabled; }
+ void setEnabled(bool enabled);
+
+ const BreakpointParameters &parameters() const { return m_params; }
+
+private:
+ friend class BreakHandler;
+ friend class BreakpointManager;
+ friend class BreakpointMarker;
+ friend class GlobalBreakpointMarker;
+
+ void updateMarker();
+ void updateMarkerIcon();
+ void destroyMarker();
+ void scheduleSynchronization();
+ QPointer<DebuggerEngine> usingEngine() const;
- BreakpointModelId id() const;
- bool isLocatedAt(const QString &fileName, int lineNumber,
- bool useMarkerPosition) const;
+ bool isEngineRunning() const;
+
+ const int m_modelId;
+ BreakpointParameters m_params;
+ GlobalBreakpointMarker *m_marker = nullptr; // The primary marker set by the user.
+};
+
+using GlobalBreakpoint = QPointer<GlobalBreakpointItem>;
+using GlobalBreakpoints = QList<GlobalBreakpoint>;
+
+class BreakpointItem : public QObject, public Utils::TypedTreeItem<SubBreakpointItem>
+{
+ Q_DECLARE_TR_FUNCTIONS(Debugger::Internal::BreakHandler)
+
+public:
+ explicit BreakpointItem(const GlobalBreakpoint &gbp);
+ ~BreakpointItem() final;
+
+ QVariant data(int column, int role) const final;
QIcon icon() const;
- BreakpointState state() const;
- void setEngine(DebuggerEngine *engine);
-
- // State transitions.
- void notifyBreakpointChangeAfterInsertNeeded();
- void notifyBreakpointInsertProceeding();
- void notifyBreakpointInsertOk();
- void notifyBreakpointInsertFailed();
- void notifyBreakpointChangeOk();
- void notifyBreakpointChangeProceeding();
- void notifyBreakpointChangeFailed();
- void notifyBreakpointPending();
- void notifyBreakpointRemoveProceeding();
- void notifyBreakpointRemoveOk();
- void notifyBreakpointRemoveFailed();
- void notifyBreakpointReleased();
- void notifyBreakpointNeedsReinsertion();
- void notifyBreakpointAdjusted(const BreakpointParameters &params);
-
- void update();
-
- void gotoLocation() const;
-
- // Getter retrieves property value.
- // Setter sets property value and triggers update if changed.
- // Only use setters when it is safe to assume that the breakpoint still
- // exist. That's not the case if the event loop could run after you
- // obtained the BreakpointItem pointer.
- BreakpointPathUsage pathUsage() const;
- void setPathUsage(const BreakpointPathUsage &u);
- QString condition() const;
- void setCondition(const QString &condition);
- int ignoreCount() const;
- void setIgnoreCount(const int &count);
- int threadSpec() const;
- void setThreadSpec(const int &spec);
- QString fileName() const;
- void setFileName(const QString &fileName);
- QString functionName() const;
- void setFunctionName(const QString &functionName);
- QString expression() const;
- void setExpression(const QString &expression);
- QString message() const;
- QString command() const;
- void setCommand(const QString &command);
- void setMessage(const QString &m);
- BreakpointType type() const;
- void setType(const BreakpointType &type);
- quint64 address() const;
- void setAddress(const quint64 &address);
- int lineNumber() const;
- void changeBreakpointData(const BreakpointParameters &data);
- bool isEnabled() const;
- void setEnabled(bool on) const;
- void updateFileNameFromMarker(const QString &fileName);
- void updateLineNumberFromMarker(int lineNumber);
- void changeLineNumberFromMarker(int lineNumber);
+
void setMarkerFileAndLine(const QString &fileName, int lineNumber);
- bool isWatchpoint() const;
- bool isTracepoint() const;
- void setTracepoint(bool on);
- DebuggerEngine *engine() const;
- const BreakpointResponse &response() const;
- void setResponse(const BreakpointResponse &data);
bool needsChange() const;
- bool needsChildren() const;
- bool isOneShot() const;
- void insertSubBreakpoint(const BreakpointResponse &data);
- void removeAlienBreakpoint();
- void removeBreakpoint() const;
+ SubBreakpoint findOrCreateSubBreakpoint(const QString &responseId);
+ QString markerFileName() const;
+ int markerLineNumber() const;
- QString msgWatchpointByAddressTriggered(int number, quint64 address) const;
- QString msgWatchpointByAddressTriggered(
- int number, quint64 address, const QString &threadId) const;
- QString msgWatchpointByExpressionTriggered(int number, const QString &expr) const;
- QString msgWatchpointByExpressionTriggered(
- int number, const QString &expr, const QString &threadId) const;
- QString msgBreakpointTriggered(int number, const QString &threadId) const;
+ const BreakpointParameters &requestedParameters() const;
+ void addToCommand(DebuggerCommand *cmd) const;
+ void updateFromGdbOutput(const GdbMi &bkpt);
+
+ int modelId() const;
+ QString responseId() const { return m_responseId; }
+ QString displayName() const { return m_displayName; }
+ QString toolTip() const;
+ QString shortToolTip() const;
+ BreakpointState state() const { return m_state; }
+ BreakpointType type() const { return m_parameters.type; }
+ BreakpointPathUsage pathUsage() const;
+ const BreakpointParameters parameters() const { return m_parameters; }
+
+ QString condition() const { return m_parameters.condition; }
+ int ignoreCount() const { return m_parameters.ignoreCount; }
+ int threadSpec() const { return m_parameters.threadSpec; }
+ QString fileName() const { return m_parameters.fileName; }
+ QString functionName() const { return m_parameters.functionName; }
+ QString expression() const { return m_parameters.expression; }
+ QString message() const { return m_parameters.message; }
+ QString command() const { return m_parameters.command; }
+ quint64 address() const { return m_parameters.address; }
+ int lineNumber() const { return m_parameters.lineNumber; }
+ bool isEnabled() const { return m_parameters.enabled; }
+ bool isWatchpoint() const { return m_parameters.isWatchpoint(); }
+ bool isTracepoint() const { return m_parameters.isTracepoint(); }
+ bool isOneShot() const { return m_parameters.oneShot; }
+ bool isPending() const { return m_parameters.pending; }
+
+ void setLineNumber(int lineNumber) { m_parameters.lineNumber = lineNumber; }
+ void setFileName(const QString &fileName) { m_parameters.fileName = fileName; }
+ void setFunctionName(const QString &functionName) { m_parameters.functionName = functionName; }
+ void setPending(bool pending);
+ void setResponseId(const QString &str) { m_responseId = str; }
+ void setDisplayName(const QString &name) { m_displayName = name; }
+ void setParameters(const BreakpointParameters &value);
+ void setAddress(quint64 address) { m_parameters.address = address; }
+ void setEnabled(bool on);
+ void setHitCount(int hitCount) { m_parameters.hitCount = hitCount; }
+ void setThreadSpec(int threadSpec) { m_parameters.threadSpec = threadSpec; }
+ void setIgnoreCount(int count) { m_parameters.ignoreCount = count; }
+ void setCommand(const QString &command) { m_parameters.command = command; }
+ void setCondition(const QString &condition) { m_parameters.condition = condition; }
+
+ QString msgWatchpointByAddressTriggered(quint64 address) const;
+ QString msgWatchpointByAddressTriggered(quint64 address, const QString &threadId) const;
+ QString msgWatchpointByExpressionTriggered(const QString &expr) const;
+ QString msgWatchpointByExpressionTriggered(const QString &expr, const QString &threadId) const;
+ QString msgBreakpointTriggered(const QString &threadId) const;
+
+ friend class BreakpointManager;
+ friend class BreakHandler;
+ friend class DebuggerEngine;
-private:
- void gotoState(BreakpointState target, BreakpointState assumedCurrent);
+ void adjustMarker();
- friend class BreakHandler;
- explicit Breakpoint(BreakpointItem *b);
+ void deleteBreakpoint();
+ void deleteGlobalOrThisBreakpoint();
+
+ void updateLineNumber(int lineNumber);
+ void updateFileName(const Utils::FileName &fileName);
- QPointer<BreakpointItem> b;
+ const GlobalBreakpoint globalBreakpoint() const;
+ void gotoState(BreakpointState target, BreakpointState assumedCurrent);
+
+private:
+ void destroyMarker();
+ void updateMarker();
+ void updateMarkerIcon();
+ void setState(BreakpointState state);
+
+ const GlobalBreakpoint m_globalBreakpoint; // Origin, or null for aliens.
+ BreakpointParameters m_requestedParameters; // May differ from global value over lifetime of breakpoint.
+ BreakpointParameters m_parameters;
+ BreakpointState m_state = BreakpointNew; // Current state of breakpoint.
+ BreakpointMarker *m_marker = nullptr;
+ QString m_responseId; //!< Breakpoint number or id assigne by or used in the debugger backend.
+ QString m_displayName;
};
-inline uint qHash(const Debugger::Internal::Breakpoint &b) { return b.hash(); }
+using Breakpoint = QPointer<BreakpointItem>;
+using Breakpoints = const QList<Breakpoint>;
+using SubBreakpoints = const QList<SubBreakpoint>;
-using Breakpoints = QList<Breakpoint>;
+using BreakHandlerModel = Utils::TreeModel<Utils::TypedTreeItem<BreakpointItem>, BreakpointItem, SubBreakpointItem>;
+using BreakpointManagerModel = Utils::TreeModel<Utils::TypedTreeItem<GlobalBreakpointItem>, GlobalBreakpointItem>;
-using BreakModel = Utils::TreeModel<Utils::TypedTreeItem<BreakpointItem>, BreakpointItem, LocationItem>;
+inline uint qHash(const Debugger::Internal::SubBreakpoint &b) { return qHash(b.data()); }
+inline uint qHash(const Debugger::Internal::Breakpoint &b) { return qHash(b.data()); }
+inline uint qHash(const Debugger::Internal::GlobalBreakpoint &b) { return qHash(b.data()); }
-class BreakHandler : public BreakModel
+class BreakHandler : public BreakHandlerModel
{
Q_OBJECT
public:
- BreakHandler();
+ explicit BreakHandler(DebuggerEngine *engine);
+
+ QAbstractItemModel *model() { return this; }
+ const Breakpoints breakpoints() const;
void loadSessionData();
void saveSessionData();
- QAbstractItemModel *model() { return this; }
+ bool tryClaimBreakpoint(const GlobalBreakpoint &gbp);
+ void releaseAllBreakpoints();
- // The only way to add a new breakpoint.
- void appendBreakpoint(const BreakpointParameters &data);
- void handleAlienBreakpoint(const BreakpointResponse &response, DebuggerEngine *engine);
+ void handleAlienBreakpoint(const QString &responseId, const BreakpointParameters &response);
+ void removeAlienBreakpoint(const QString &responseId);
+ void requestBreakpointInsertion(const Breakpoint &bp);
+ void requestBreakpointUpdate(const Breakpoint &bp);
+ void requestBreakpointRemoval(const Breakpoint &bp);
+ void requestBreakpointEnabling(const Breakpoint &bp, bool enabled);
+ void requestSubBreakpointEnabling(const SubBreakpoint &sbp, bool enabled);
- const Breakpoints allBreakpoints() const;
- const Breakpoints engineBreakpoints(DebuggerEngine *engine) const;
- const Breakpoints unclaimedBreakpoints() const;
- QStringList engineBreakpointPaths(DebuggerEngine *engine) const;
+ void removeBreakpoint(const Breakpoint &bp);
+ void editBreakpoint(const Breakpoint &bp, QWidget *parent);
- // Find a breakpoint matching approximately the data in needle.
- Breakpoint findSimilarBreakpoint(const BreakpointResponse &needle) const;
- Breakpoint findBreakpointByResponseId(const BreakpointResponseId &resultId) const;
+ Breakpoint findBreakpointByResponseId(const QString &responseId) const;
+ SubBreakpoint findSubBreakpointByResponseId(const QString &responseId) const;
Breakpoint findWatchpoint(const BreakpointParameters &data) const;
- Breakpoint findBreakpointByFunction(const QString &functionName) const;
- Breakpoint findBreakpointByIndex(const QModelIndex &index) const;
- Breakpoints findBreakpointsByIndex(const QList<QModelIndex> &list) const;
- void updateMarkers();
+ Breakpoint findBreakpointByModelId(int modelId) const;
- Breakpoint findBreakpointByFileAndLine(const QString &fileName,
- int lineNumber, bool useMarkerPosition = true);
- Breakpoint findBreakpointByAddress(quint64 address) const;
-
- void breakByFunction(const QString &functionName);
static QString displayFromThreadSpec(int spec);
static int threadSpecFromDisplay(const QString &str);
// Convenience.
void setWatchpointAtAddress(quint64 address, unsigned size);
void setWatchpointAtExpression(const QString &exp);
+ void setBreakpointEnabled(const Breakpoint &bp, bool on);
- Breakpoint breakpointById(BreakpointModelId id) const;
- void editBreakpoint(Breakpoint bp, QWidget *parent);
+ void updateDisassemblerMarker(const Breakpoint &bp);
+ void removeDisassemblerMarker(const Breakpoint &bp);
private:
- QVariant data(const QModelIndex &idx, int role) const override;
- bool setData(const QModelIndex &idx, const QVariant &value, int role) override;
- void timerEvent(QTimerEvent *event) override;
+ Breakpoint findBreakpointByIndex(const QModelIndex &index) const;
+ Breakpoints findBreakpointsByIndex(const QList<QModelIndex> &list) const;
+ SubBreakpoint findSubBreakpointByIndex(const QModelIndex &index) const;
+ SubBreakpoints findSubBreakpointsByIndex(const QList<QModelIndex> &list) const;
+ void editBreakpoints(const Breakpoints &bps, QWidget *parent);
+
+ void gotoState(Breakpoint bp, BreakpointState target, BreakpointState assumedCurrent);
+ void gotoLocation(const Breakpoint &bp) const;
+
+ QVariant data(const QModelIndex &idx, int role) const final;
+ bool setData(const QModelIndex &idx, const QVariant &value, int role) final;
bool contextMenuEvent(const Utils::ItemViewEvent &ev);
friend class BreakpointItem;
- friend class Breakpoint;
- void loadBreakpoints();
- void saveBreakpoints();
+ DebuggerEngine * const m_engine;
+};
- void appendBreakpointInternal(const BreakpointParameters &data);
- void deleteBreakpoints(const Breakpoints &bps);
- void deleteAllBreakpoints();
- void setBreakpointsEnabled(const Breakpoints &bps, bool enabled);
- void addBreakpoint();
- void editBreakpoints(const Breakpoints &bps, QWidget *parent);
+class BreakpointManager : public BreakpointManagerModel
+{
+ Q_OBJECT
- Q_SLOT void changeLineNumberFromMarkerHelper(Debugger::Internal::BreakpointModelId id);
- Q_SLOT void deletionHelper(Debugger::Internal::BreakpointModelId id);
+public:
+ BreakpointManager();
- void scheduleSynchronization();
+ static QAbstractItemModel *model();
+
+ static const GlobalBreakpoints globalBreakpoints();
+ static void loadSessionData();
+ static void saveSessionData();
+ static void aboutToUnloadSession();
+
+ static GlobalBreakpoint createBreakpoint(const BreakpointParameters &data);
- int m_syncTimerId;
+ static GlobalBreakpoint findBreakpointByLocation(const ContextData &location);
+ // Find a breakpoint matching approximately the data in needle.
+ static GlobalBreakpoint findSimilarBreakpoint(const BreakpointParameters &needle);
+ static GlobalBreakpoint findWatchpoint(const BreakpointParameters &data);
+ static GlobalBreakpoint findBreakpointByFunction(const QString &functionName);
+
+ static void claimBreakpointsForEngine(DebuggerEngine *engine);
+ static void toggleBreakpoint(const ContextData &location, const QString &tracePointMessage = QString());
+ static void createBreakpointForEngine(const BreakpointParameters &data, DebuggerEngine *engine);
+
+ static void executeAddBreakpointDialog();
+ static void executeDeleteAllBreakpointsDialog();
+
+private:
+ static GlobalBreakpoint createBreakpointHelper(const BreakpointParameters &data);
+ static GlobalBreakpoint findBreakpointByIndex(const QModelIndex &index);
+ static GlobalBreakpoints findBreakpointsByIndex(const QList<QModelIndex> &list);
+
+ QVariant data(const QModelIndex &idx, int role) const final;
+ bool setData(const QModelIndex &idx, const QVariant &value, int role) final;
+
+ bool contextMenuEvent(const Utils::ItemViewEvent &ev);
+ void gotoLocation(const GlobalBreakpoint &gbp) const;
};
} // namespace Internal
} // namespace Debugger
-Q_DECLARE_METATYPE(Debugger::Internal::Breakpoint)