forked from qt-creator/qt-creator
Debugger: Re-work breakpoint storage handling
The actual data is now in a TreeModel. As interface to individual breakpoints there's a new Breakpoint class essentially providing a checked handle. On the user code side breakHandler()->foo(bpId) is replaced by bp.foo(). Change-Id: I82f435bad6301fce85a1d82bf6bf39e9ddba511e Reviewed-by: Christian Stenger <christian.stenger@theqtcompany.com>
This commit is contained in:
@@ -35,6 +35,9 @@
|
||||
|
||||
#include <utils/treemodel.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QPointer>
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BreakHandler
|
||||
@@ -44,9 +47,122 @@
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
|
||||
class BreakpointMarker;
|
||||
class BreakpointItem;
|
||||
class BreakHandler;
|
||||
class DebuggerEngine;
|
||||
|
||||
// Non-owning "deletion-safe" wrapper around a BreakpointItem *
|
||||
class Breakpoint
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(Debugger::Internal::BreakHandler)
|
||||
|
||||
public:
|
||||
Breakpoint() {}
|
||||
|
||||
bool isValid() const;
|
||||
operator const void *() const { return isValid() ? this : 0; }
|
||||
bool operator!() const { return !isValid(); }
|
||||
|
||||
uint hash() const;
|
||||
|
||||
const BreakpointParameters ¶meters() const;
|
||||
|
||||
BreakpointModelId id() const;
|
||||
bool isLocatedAt(const QString &fileName, int lineNumber,
|
||||
bool useMarkerPosition) const;
|
||||
|
||||
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);
|
||||
QByteArray condition() const;
|
||||
void setCondition(const QByteArray &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;
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
private:
|
||||
void gotoState(BreakpointState target, BreakpointState assumedCurrent);
|
||||
|
||||
friend class BreakHandler;
|
||||
explicit Breakpoint(BreakpointItem *b);
|
||||
|
||||
QPointer<BreakpointItem> b;
|
||||
};
|
||||
|
||||
inline uint qHash(const Debugger::Internal::Breakpoint &b) { return b.hash(); }
|
||||
|
||||
typedef QList<Breakpoint> Breakpoints;
|
||||
|
||||
class BreakHandler : public Utils::TreeModel
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -62,21 +178,19 @@ public:
|
||||
// The only way to add a new breakpoint.
|
||||
void appendBreakpoint(const BreakpointParameters &data);
|
||||
void handleAlienBreakpoint(const BreakpointResponse &response, DebuggerEngine *engine);
|
||||
void insertSubBreakpoint(BreakpointModelId id, const BreakpointResponse &data);
|
||||
void removeAlienBreakpoint(BreakpointModelId id);
|
||||
|
||||
BreakpointModelIds allBreakpointIds() const;
|
||||
BreakpointModelIds engineBreakpointIds(DebuggerEngine *engine) const;
|
||||
BreakpointModelIds unclaimedBreakpointIds() const;
|
||||
Breakpoints allBreakpoints() const;
|
||||
Breakpoints engineBreakpoints(DebuggerEngine *engine) const;
|
||||
Breakpoints unclaimedBreakpoints() const;
|
||||
QStringList engineBreakpointPaths(DebuggerEngine *engine) const;
|
||||
|
||||
// Find a breakpoint matching approximately the data in needle.
|
||||
BreakpointModelId findSimilarBreakpoint(const BreakpointResponse &needle) const;
|
||||
BreakpointModelId findBreakpointByResponseId(const BreakpointResponseId &resultId) const;
|
||||
BreakpointModelId findWatchpoint(const BreakpointParameters &data) const;
|
||||
BreakpointModelId findBreakpointByFunction(const QString &functionName) const;
|
||||
BreakpointModelId findBreakpointByIndex(const QModelIndex &index) const;
|
||||
BreakpointModelIds findBreakpointsByIndex(const QList<QModelIndex> &list) const;
|
||||
Breakpoint findSimilarBreakpoint(const BreakpointResponse &needle) const;
|
||||
Breakpoint findBreakpointByResponseId(const BreakpointResponseId &resultId) 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();
|
||||
|
||||
static QIcon breakpointIcon();
|
||||
@@ -86,77 +200,11 @@ public:
|
||||
static QIcon watchpointIcon();
|
||||
static QIcon tracepointIcon();
|
||||
|
||||
BreakpointModelId findBreakpointByFileAndLine(const QString &fileName,
|
||||
Breakpoint findBreakpointByFileAndLine(const QString &fileName,
|
||||
int lineNumber, bool useMarkerPosition = true);
|
||||
BreakpointModelId findBreakpointByAddress(quint64 address) const;
|
||||
Breakpoint findBreakpointByAddress(quint64 address) const;
|
||||
|
||||
void breakByFunction(const QString &functionName);
|
||||
void removeBreakpoint(BreakpointModelId id);
|
||||
QIcon icon(BreakpointModelId id) const;
|
||||
void gotoLocation(BreakpointModelId id) const;
|
||||
|
||||
// Getter retrieves property value.
|
||||
// Setter sets property value and triggers update if changed.
|
||||
BreakpointPathUsage pathUsage(BreakpointModelId id) const;
|
||||
void setPathUsage(BreakpointModelId, const BreakpointPathUsage &u);
|
||||
QByteArray condition(BreakpointModelId id) const;
|
||||
void setCondition(BreakpointModelId, const QByteArray &condition);
|
||||
int ignoreCount(BreakpointModelId id) const;
|
||||
void setIgnoreCount(BreakpointModelId, const int &count);
|
||||
int threadSpec(BreakpointModelId id) const;
|
||||
void setThreadSpec(BreakpointModelId, const int &spec);
|
||||
QString fileName(BreakpointModelId id) const;
|
||||
void setFileName(BreakpointModelId, const QString &fileName);
|
||||
QString functionName(BreakpointModelId id) const;
|
||||
void setFunctionName(BreakpointModelId, const QString &functionName);
|
||||
QString expression(BreakpointModelId id) const;
|
||||
void setExpression(BreakpointModelId, const QString &expression);
|
||||
QString message(BreakpointModelId id) const;
|
||||
void setMessage(BreakpointModelId, const QString &m);
|
||||
BreakpointType type(BreakpointModelId id) const;
|
||||
void setType(BreakpointModelId id, const BreakpointType &type);
|
||||
quint64 address(BreakpointModelId id) const;
|
||||
void setAddress(BreakpointModelId id, const quint64 &address);
|
||||
int lineNumber(BreakpointModelId id) const;
|
||||
void changeBreakpointData(BreakpointModelId id, const BreakpointParameters &data,
|
||||
BreakpointParts parts);
|
||||
const BreakpointParameters &breakpointData(BreakpointModelId id) const;
|
||||
BreakpointState state(BreakpointModelId id) const;
|
||||
bool isEnabled(BreakpointModelId id) const;
|
||||
void setEnabled(BreakpointModelId id, bool on);
|
||||
void updateFileNameFromMarker(BreakpointModelId id, const QString &fileName);
|
||||
void updateLineNumberFromMarker(BreakpointModelId id, int lineNumber);
|
||||
void changeLineNumberFromMarker(BreakpointModelId id, int lineNumber);
|
||||
void setMarkerFileAndLine(BreakpointModelId id,
|
||||
const QString &fileName, int lineNumber);
|
||||
bool isOneShot(BreakpointModelId id) const;
|
||||
bool isWatchpoint(BreakpointModelId id) const;
|
||||
bool isTracepoint(BreakpointModelId id) const;
|
||||
void setTracepoint(BreakpointModelId, bool on);
|
||||
DebuggerEngine *engine(BreakpointModelId id) const;
|
||||
void setEngine(BreakpointModelId id, DebuggerEngine *engine);
|
||||
const BreakpointResponse &response(BreakpointModelId id) const;
|
||||
void setResponse(BreakpointModelId id, const BreakpointResponse &data);
|
||||
bool needsChange(BreakpointModelId id) const;
|
||||
bool needsChildren(BreakpointModelId id) const;
|
||||
|
||||
// State transitions.
|
||||
void notifyBreakpointChangeAfterInsertNeeded(BreakpointModelId id);
|
||||
void notifyBreakpointInsertProceeding(BreakpointModelId id);
|
||||
void notifyBreakpointInsertOk(BreakpointModelId id);
|
||||
void notifyBreakpointInsertFailed(BreakpointModelId id);
|
||||
void notifyBreakpointChangeOk(BreakpointModelId id);
|
||||
void notifyBreakpointChangeProceeding(BreakpointModelId id);
|
||||
void notifyBreakpointChangeFailed(BreakpointModelId id);
|
||||
void notifyBreakpointPending(BreakpointModelId id);
|
||||
void notifyBreakpointRemoveProceeding(BreakpointModelId id);
|
||||
void notifyBreakpointRemoveOk(BreakpointModelId id);
|
||||
void notifyBreakpointRemoveFailed(BreakpointModelId id);
|
||||
void notifyBreakpointReleased(BreakpointModelId id);
|
||||
void notifyBreakpointNeedsReinsertion(BreakpointModelId id);
|
||||
void notifyBreakpointAdjusted(BreakpointModelId id,
|
||||
const BreakpointParameters &data);
|
||||
|
||||
static QString displayFromThreadSpec(int spec);
|
||||
static int threadSpecFromDisplay(const QString &str);
|
||||
|
||||
@@ -164,54 +212,22 @@ public:
|
||||
void setWatchpointAtAddress(quint64 address, unsigned size);
|
||||
void setWatchpointAtExpression(const QString &exp);
|
||||
|
||||
Breakpoint breakpointById(BreakpointModelId id) const;
|
||||
|
||||
signals:
|
||||
void requestExpansion(QModelIndex);
|
||||
|
||||
private:
|
||||
bool isEngineRunning(BreakpointModelId id) const;
|
||||
void setState(BreakpointModelId id, BreakpointState state);
|
||||
friend class BreakpointItem;
|
||||
friend class Breakpoint;
|
||||
|
||||
void loadBreakpoints();
|
||||
void saveBreakpoints();
|
||||
void cleanupBreakpoint(BreakpointModelId id);
|
||||
|
||||
void appendBreakpointInternal(const BreakpointParameters &data);
|
||||
Q_SLOT void changeLineNumberFromMarkerHelper(Debugger::Internal::BreakpointModelId id, int lineNumber);
|
||||
|
||||
struct BreakpointItem : public Utils::TreeItem
|
||||
{
|
||||
BreakpointItem();
|
||||
~BreakpointItem();
|
||||
|
||||
int columnCount() const { return 8; }
|
||||
QVariant data(int column, int role) const;
|
||||
|
||||
void destroyMarker();
|
||||
bool needsChange() const;
|
||||
bool isLocatedAt(const QString &fileName, int lineNumber,
|
||||
bool useMarkerPosition) const;
|
||||
void updateMarker();
|
||||
void updateMarkerIcon();
|
||||
QString toToolTip() const;
|
||||
QString markerFileName() const;
|
||||
int markerLineNumber() const;
|
||||
QIcon icon() const;
|
||||
|
||||
BreakpointModelId id;
|
||||
BreakpointParameters params;
|
||||
BreakpointState state; // Current state of breakpoint.
|
||||
DebuggerEngine *engine; // Engine currently handling the breakpoint.
|
||||
BreakpointResponse response;
|
||||
BreakpointMarker *marker;
|
||||
};
|
||||
|
||||
struct LocationItem : public Utils::TreeItem
|
||||
{
|
||||
int columnCount() const { return 8; }
|
||||
QVariant data(int column, int role) const;
|
||||
|
||||
BreakpointResponse params;
|
||||
};
|
||||
|
||||
BreakpointItem *breakpointById(BreakpointModelId id) const;
|
||||
Q_SLOT void changeLineNumberFromMarkerHelper(Debugger::Internal::BreakpointModelId id);
|
||||
Q_SLOT void deletionHelper(Debugger::Internal::BreakpointModelId id);
|
||||
|
||||
void scheduleSynchronization();
|
||||
void timerEvent(QTimerEvent *event);
|
||||
@@ -221,4 +237,6 @@ private:
|
||||
} // namespace Internal
|
||||
} // namespace Debugger
|
||||
|
||||
Q_DECLARE_METATYPE(Debugger::Internal::Breakpoint)
|
||||
|
||||
#endif // DEBUGGER_BREAKHANDLER_H
|
||||
|
||||
Reference in New Issue
Block a user