Debugger: Fix removal of breakpoint marks in disassembler view

Task-number: QTCREATORBUG-14973
Change-Id: I6dfceefe6d8b1404c2a553dbeebd7dccefa1a624
Reviewed-by: Christian Stenger <christian.stenger@theqtcompany.com>
This commit is contained in:
hjk
2015-08-31 16:35:24 +02:00
parent 44a8e937e3
commit cfb2b2186e
5 changed files with 87 additions and 53 deletions

View File

@@ -104,8 +104,6 @@ public:
void changeLineNumberFromMarker(int lineNumber); void changeLineNumberFromMarker(int lineNumber);
bool isLocatedAt(const QString &fileName, int lineNumber, bool useMarkerPosition) const; bool isLocatedAt(const QString &fileName, int lineNumber, bool useMarkerPosition) const;
bool needsChildren() const;
void setMarkerFileAndLine(const QString &fileName, int lineNumber); void setMarkerFileAndLine(const QString &fileName, int lineNumber);
void insertSubBreakpoint(const BreakpointResponse &params); void insertSubBreakpoint(const BreakpointResponse &params);
@@ -808,6 +806,7 @@ void Breakpoint::removeAlienBreakpoint()
void Breakpoint::removeBreakpoint() const void Breakpoint::removeBreakpoint() const
{ {
if (b)
b->removeBreakpoint(); b->removeBreakpoint();
} }
@@ -834,11 +833,6 @@ void Breakpoint::setMarkerFileAndLine(const QString &fileName, int lineNumber)
b->setMarkerFileAndLine(fileName, lineNumber); b->setMarkerFileAndLine(fileName, lineNumber);
} }
bool BreakpointItem::needsChildren() const
{
return m_response.multiple && rowCount() == 0;
}
void Breakpoint::setTracepoint(bool on) void Breakpoint::setTracepoint(bool on)
{ {
if (b->m_params.tracepoint == on) if (b->m_params.tracepoint == on)
@@ -971,6 +965,8 @@ void Breakpoint::notifyBreakpointInsertProceeding()
void Breakpoint::notifyBreakpointInsertOk() void Breakpoint::notifyBreakpointInsertOk()
{ {
gotoState(BreakpointInserted, BreakpointInsertProceeding); gotoState(BreakpointInserted, BreakpointInsertProceeding);
if (b->m_engine)
b->m_engine->updateBreakpointMarker(*this);
} }
void Breakpoint::notifyBreakpointInsertFailed() void Breakpoint::notifyBreakpointInsertFailed()
@@ -987,6 +983,8 @@ void Breakpoint::notifyBreakpointRemoveOk()
{ {
QTC_ASSERT(b, return); QTC_ASSERT(b, return);
QTC_ASSERT(b->m_state == BreakpointRemoveProceeding, qDebug() << b->m_state); QTC_ASSERT(b->m_state == BreakpointRemoveProceeding, qDebug() << b->m_state);
if (b->m_engine)
b->m_engine->removeBreakpointMarker(*this);
b->deleteThis(); b->deleteThis();
} }
@@ -994,6 +992,8 @@ void Breakpoint::notifyBreakpointRemoveFailed()
{ {
QTC_ASSERT(b, return); QTC_ASSERT(b, return);
QTC_ASSERT(b->m_state == BreakpointRemoveProceeding, qDebug() << b->m_state); QTC_ASSERT(b->m_state == BreakpointRemoveProceeding, qDebug() << b->m_state);
if (b->m_engine)
b->m_engine->removeBreakpointMarker(*this);
b->deleteThis(); b->deleteThis();
} }
@@ -1301,6 +1301,8 @@ void Breakpoint::changeBreakpointData(const BreakpointParameters &params)
if (params == b->m_params) if (params == b->m_params)
return; return;
b->m_params = params; b->m_params = params;
if (b->m_engine)
b->m_engine->updateBreakpointMarker(*this);
b->destroyMarker(); b->destroyMarker();
b->updateMarker(); b->updateMarker();
b->update(); b->update();
@@ -1331,8 +1333,6 @@ BreakpointItem::~BreakpointItem()
void BreakpointItem::destroyMarker() void BreakpointItem::destroyMarker()
{ {
if (m_engine)
m_engine->updateBreakpointMarkers();
if (m_marker) { if (m_marker) {
BreakpointMarker *m = m_marker; BreakpointMarker *m = m_marker;
m->m_bp = 0; m->m_bp = 0;

View File

@@ -1339,9 +1339,14 @@ QString DebuggerEngine::toFileInProject(const QUrl &fileUrl)
return d->m_fileFinder.findFile(fileUrl); return d->m_fileFinder.findFile(fileUrl);
} }
void DebuggerEngine::updateBreakpointMarkers() void DebuggerEngine::removeBreakpointMarker(const Breakpoint &bp)
{ {
d->m_disassemblerAgent.updateBreakpointMarkers(); d->m_disassemblerAgent.removeBreakpointMarker(bp);
}
void DebuggerEngine::updateBreakpointMarker(const Breakpoint &bp)
{
d->m_disassemblerAgent.updateBreakpointMarker(bp);
} }
bool DebuggerEngine::debuggerActionsEnabled() const bool DebuggerEngine::debuggerActionsEnabled() const
@@ -1638,7 +1643,6 @@ void DebuggerEngine::attemptBreakpointSynchronization()
if (done) { if (done) {
showMessage(_("BREAKPOINTS ARE SYNCHRONIZED")); showMessage(_("BREAKPOINTS ARE SYNCHRONIZED"));
d->m_disassemblerAgent.updateBreakpointMarkers();
} else { } else {
showMessage(_("BREAKPOINTS ARE NOT FULLY SYNCHRONIZED")); showMessage(_("BREAKPOINTS ARE NOT FULLY SYNCHRONIZED"));
} }

View File

@@ -320,7 +320,8 @@ public:
virtual void notifyInferiorIll(); virtual void notifyInferiorIll();
QString toFileInProject(const QUrl &fileUrl); QString toFileInProject(const QUrl &fileUrl);
void updateBreakpointMarkers(); void updateBreakpointMarker(const Breakpoint &bp);
void removeBreakpointMarker(const Breakpoint &bp);
signals: signals:
void stateChanged(Debugger::DebuggerState state); void stateChanged(Debugger::DebuggerState state);

View File

@@ -61,6 +61,30 @@ using namespace TextEditor;
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal {
///////////////////////////////////////////////////////////////////////
//
// DisassemblerBreakpointMarker
//
///////////////////////////////////////////////////////////////////////
// The red blob on the left side in the cpp editor.
class DisassemblerBreakpointMarker : public TextMark
{
public:
DisassemblerBreakpointMarker(const Breakpoint &bp, int lineNumber)
: TextMark(QString(), lineNumber, Constants::TEXT_MARK_CATEGORY_BREAKPOINT), m_bp(bp)
{
setIcon(bp.icon());
setPriority(TextMark::NormalPriority);
}
bool isClickable() const { return true; }
void clicked() { m_bp.removeBreakpoint(); }
public:
Breakpoint m_bp;
};
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
// //
// FrameKey // FrameKey
@@ -102,14 +126,14 @@ public:
DisassemblerAgentPrivate(DebuggerEngine *engine); DisassemblerAgentPrivate(DebuggerEngine *engine);
~DisassemblerAgentPrivate(); ~DisassemblerAgentPrivate();
void configureMimeType(); void configureMimeType();
DisassemblerLines contentsAtCurrentLocation() const; int lineForAddress(quint64 address) const;
public: public:
QPointer<TextDocument> document; QPointer<TextDocument> document;
Location location; Location location;
QPointer<DebuggerEngine> engine; QPointer<DebuggerEngine> engine;
LocationMark locationMark; LocationMark locationMark;
QList<TextMark *> breakpointMarks; QList<DisassemblerBreakpointMarker *> breakpointMarks;
QList<CacheEntry> cache; QList<CacheEntry> cache;
QString mimeType; QString mimeType;
bool resetLocationScheduled; bool resetLocationScheduled;
@@ -130,14 +154,14 @@ DisassemblerAgentPrivate::~DisassemblerAgentPrivate()
qDeleteAll(breakpointMarks); qDeleteAll(breakpointMarks);
} }
DisassemblerLines DisassemblerAgentPrivate::contentsAtCurrentLocation() const int DisassemblerAgentPrivate::lineForAddress(quint64 address) const
{ {
for (int i = 0, n = cache.size(); i != n; ++i) { for (int i = 0, n = cache.size(); i != n; ++i) {
const CacheEntry &entry = cache.at(i); const CacheEntry &entry = cache.at(i);
if (entry.first.matches(location)) if (entry.first.matches(location))
return entry.second; return entry.second.lineForAddress(address);
} }
return DisassemblerLines(); return 0;
} }
@@ -310,15 +334,17 @@ void DisassemblerAgent::setContentsToDocument(const DisassemblerLines &contents)
d->document->setPreferredDisplayName(_("Disassembler (%1)") d->document->setPreferredDisplayName(_("Disassembler (%1)")
.arg(d->location.functionName())); .arg(d->location.functionName()));
updateBreakpointMarkers(); Breakpoints bps = breakHandler()->engineBreakpoints(d->engine);
foreach (Breakpoint bp, bps)
updateBreakpointMarker(bp);
updateLocationMarker(); updateLocationMarker();
} }
void DisassemblerAgent::updateLocationMarker() void DisassemblerAgent::updateLocationMarker()
{ {
QTC_ASSERT(d->document, return); QTC_ASSERT(d->document, return);
const DisassemblerLines contents = d->contentsAtCurrentLocation(); int lineNumber = d->lineForAddress(d->location.address());
int lineNumber = contents.lineForAddress(d->location.address());
if (d->location.needsMarker()) { if (d->location.needsMarker()) {
d->document->removeMark(&d->locationMark); d->document->removeMark(&d->locationMark);
d->locationMark.updateLineNumber(lineNumber); d->locationMark.updateLineNumber(lineNumber);
@@ -331,27 +357,32 @@ void DisassemblerAgent::updateLocationMarker()
textEditor->gotoLine(lineNumber); textEditor->gotoLine(lineNumber);
} }
void DisassemblerAgent::updateBreakpointMarkers() void DisassemblerAgent::removeBreakpointMarker(const Breakpoint &bp)
{ {
if (!d->document) if (!d->document)
return; return;
Breakpoints bps = breakHandler()->engineBreakpoints(d->engine); BreakpointModelId id = bp.id();
if (bps.isEmpty()) foreach (DisassemblerBreakpointMarker *marker, d->breakpointMarks) {
return; if (marker->m_bp.id() == id) {
d->breakpointMarks.removeOne(marker);
const DisassemblerLines contents = d->contentsAtCurrentLocation();
foreach (TextMark *marker, d->breakpointMarks)
d->document->removeMark(marker); d->document->removeMark(marker);
qDeleteAll(d->breakpointMarks); delete marker;
d->breakpointMarks.clear(); return;
foreach (Breakpoint bp, bps) { }
}
}
void DisassemblerAgent::updateBreakpointMarker(const Breakpoint &bp)
{
removeBreakpointMarker(bp);
const quint64 address = bp.response().address; const quint64 address = bp.response().address;
if (!address) if (!address)
continue; return;
int lineNumber = contents.lineForAddress(address);
int lineNumber = d->lineForAddress(address);
if (!lineNumber) if (!lineNumber)
continue; return;
// HACK: If it's a FileAndLine breakpoint, and there's a source line // HACK: If it's a FileAndLine breakpoint, and there's a source line
// above, move the marker up there. That allows setting and removing // above, move the marker up there. That allows setting and removing
@@ -362,13 +393,9 @@ void DisassemblerAgent::updateBreakpointMarkers()
--lineNumber; --lineNumber;
} }
TextMark *marker = new TextMark(QString(), lineNumber, auto marker = new DisassemblerBreakpointMarker(bp, lineNumber);
Constants::TEXT_MARK_CATEGORY_BREAKPOINT);
marker->setIcon(bp.icon());
marker->setPriority(TextMark::NormalPriority);
d->breakpointMarks.append(marker); d->breakpointMarks.append(marker);
d->document->addMark(marker); d->document->addMark(marker);
}
} }
quint64 DisassemblerAgent::address() const quint64 DisassemblerAgent::address() const

View File

@@ -36,6 +36,7 @@
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal {
class Breakpoint;
class DebuggerEngine; class DebuggerEngine;
class DisassemblerAgentPrivate; class DisassemblerAgentPrivate;
class DisassemblerLines; class DisassemblerLines;
@@ -56,7 +57,8 @@ public:
void resetLocation(); void resetLocation();
void setContents(const DisassemblerLines &contents); void setContents(const DisassemblerLines &contents);
void updateLocationMarker(); void updateLocationMarker();
void updateBreakpointMarkers(); void updateBreakpointMarker(const Breakpoint &bp);
void removeBreakpointMarker(const Breakpoint &bp);
// Mimetype: "text/a-asm" or some specialized architecture // Mimetype: "text/a-asm" or some specialized architecture
QString mimeType() const; QString mimeType() const;