diff options
Diffstat (limited to 'src/plugins/debugger/breakhandler.h')
-rw-r--r-- | src/plugins/debugger/breakhandler.h | 367 |
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 ¶meters() 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 ¶meters() 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 ¶ms); - - 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) |