forked from qt-creator/qt-creator
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:
@@ -104,8 +104,6 @@ public:
|
||||
void changeLineNumberFromMarker(int lineNumber);
|
||||
bool isLocatedAt(const QString &fileName, int lineNumber, bool useMarkerPosition) const;
|
||||
|
||||
bool needsChildren() const;
|
||||
|
||||
void setMarkerFileAndLine(const QString &fileName, int lineNumber);
|
||||
|
||||
void insertSubBreakpoint(const BreakpointResponse ¶ms);
|
||||
@@ -808,6 +806,7 @@ void Breakpoint::removeAlienBreakpoint()
|
||||
|
||||
void Breakpoint::removeBreakpoint() const
|
||||
{
|
||||
if (b)
|
||||
b->removeBreakpoint();
|
||||
}
|
||||
|
||||
@@ -834,11 +833,6 @@ void Breakpoint::setMarkerFileAndLine(const QString &fileName, int lineNumber)
|
||||
b->setMarkerFileAndLine(fileName, lineNumber);
|
||||
}
|
||||
|
||||
bool BreakpointItem::needsChildren() const
|
||||
{
|
||||
return m_response.multiple && rowCount() == 0;
|
||||
}
|
||||
|
||||
void Breakpoint::setTracepoint(bool on)
|
||||
{
|
||||
if (b->m_params.tracepoint == on)
|
||||
@@ -971,6 +965,8 @@ void Breakpoint::notifyBreakpointInsertProceeding()
|
||||
void Breakpoint::notifyBreakpointInsertOk()
|
||||
{
|
||||
gotoState(BreakpointInserted, BreakpointInsertProceeding);
|
||||
if (b->m_engine)
|
||||
b->m_engine->updateBreakpointMarker(*this);
|
||||
}
|
||||
|
||||
void Breakpoint::notifyBreakpointInsertFailed()
|
||||
@@ -987,6 +983,8 @@ void Breakpoint::notifyBreakpointRemoveOk()
|
||||
{
|
||||
QTC_ASSERT(b, return);
|
||||
QTC_ASSERT(b->m_state == BreakpointRemoveProceeding, qDebug() << b->m_state);
|
||||
if (b->m_engine)
|
||||
b->m_engine->removeBreakpointMarker(*this);
|
||||
b->deleteThis();
|
||||
}
|
||||
|
||||
@@ -994,6 +992,8 @@ void Breakpoint::notifyBreakpointRemoveFailed()
|
||||
{
|
||||
QTC_ASSERT(b, return);
|
||||
QTC_ASSERT(b->m_state == BreakpointRemoveProceeding, qDebug() << b->m_state);
|
||||
if (b->m_engine)
|
||||
b->m_engine->removeBreakpointMarker(*this);
|
||||
b->deleteThis();
|
||||
}
|
||||
|
||||
@@ -1301,6 +1301,8 @@ void Breakpoint::changeBreakpointData(const BreakpointParameters ¶ms)
|
||||
if (params == b->m_params)
|
||||
return;
|
||||
b->m_params = params;
|
||||
if (b->m_engine)
|
||||
b->m_engine->updateBreakpointMarker(*this);
|
||||
b->destroyMarker();
|
||||
b->updateMarker();
|
||||
b->update();
|
||||
@@ -1331,8 +1333,6 @@ BreakpointItem::~BreakpointItem()
|
||||
|
||||
void BreakpointItem::destroyMarker()
|
||||
{
|
||||
if (m_engine)
|
||||
m_engine->updateBreakpointMarkers();
|
||||
if (m_marker) {
|
||||
BreakpointMarker *m = m_marker;
|
||||
m->m_bp = 0;
|
||||
|
||||
@@ -1339,9 +1339,14 @@ QString DebuggerEngine::toFileInProject(const QUrl &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
|
||||
@@ -1638,7 +1643,6 @@ void DebuggerEngine::attemptBreakpointSynchronization()
|
||||
|
||||
if (done) {
|
||||
showMessage(_("BREAKPOINTS ARE SYNCHRONIZED"));
|
||||
d->m_disassemblerAgent.updateBreakpointMarkers();
|
||||
} else {
|
||||
showMessage(_("BREAKPOINTS ARE NOT FULLY SYNCHRONIZED"));
|
||||
}
|
||||
|
||||
@@ -320,7 +320,8 @@ public:
|
||||
virtual void notifyInferiorIll();
|
||||
|
||||
QString toFileInProject(const QUrl &fileUrl);
|
||||
void updateBreakpointMarkers();
|
||||
void updateBreakpointMarker(const Breakpoint &bp);
|
||||
void removeBreakpointMarker(const Breakpoint &bp);
|
||||
|
||||
signals:
|
||||
void stateChanged(Debugger::DebuggerState state);
|
||||
|
||||
@@ -61,6 +61,30 @@ using namespace TextEditor;
|
||||
namespace Debugger {
|
||||
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
|
||||
@@ -102,14 +126,14 @@ public:
|
||||
DisassemblerAgentPrivate(DebuggerEngine *engine);
|
||||
~DisassemblerAgentPrivate();
|
||||
void configureMimeType();
|
||||
DisassemblerLines contentsAtCurrentLocation() const;
|
||||
int lineForAddress(quint64 address) const;
|
||||
|
||||
public:
|
||||
QPointer<TextDocument> document;
|
||||
Location location;
|
||||
QPointer<DebuggerEngine> engine;
|
||||
LocationMark locationMark;
|
||||
QList<TextMark *> breakpointMarks;
|
||||
QList<DisassemblerBreakpointMarker *> breakpointMarks;
|
||||
QList<CacheEntry> cache;
|
||||
QString mimeType;
|
||||
bool resetLocationScheduled;
|
||||
@@ -130,14 +154,14 @@ DisassemblerAgentPrivate::~DisassemblerAgentPrivate()
|
||||
qDeleteAll(breakpointMarks);
|
||||
}
|
||||
|
||||
DisassemblerLines DisassemblerAgentPrivate::contentsAtCurrentLocation() const
|
||||
int DisassemblerAgentPrivate::lineForAddress(quint64 address) const
|
||||
{
|
||||
for (int i = 0, n = cache.size(); i != n; ++i) {
|
||||
const CacheEntry &entry = cache.at(i);
|
||||
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)")
|
||||
.arg(d->location.functionName()));
|
||||
|
||||
updateBreakpointMarkers();
|
||||
Breakpoints bps = breakHandler()->engineBreakpoints(d->engine);
|
||||
foreach (Breakpoint bp, bps)
|
||||
updateBreakpointMarker(bp);
|
||||
|
||||
updateLocationMarker();
|
||||
}
|
||||
|
||||
void DisassemblerAgent::updateLocationMarker()
|
||||
{
|
||||
QTC_ASSERT(d->document, return);
|
||||
const DisassemblerLines contents = d->contentsAtCurrentLocation();
|
||||
int lineNumber = contents.lineForAddress(d->location.address());
|
||||
int lineNumber = d->lineForAddress(d->location.address());
|
||||
if (d->location.needsMarker()) {
|
||||
d->document->removeMark(&d->locationMark);
|
||||
d->locationMark.updateLineNumber(lineNumber);
|
||||
@@ -331,27 +357,32 @@ void DisassemblerAgent::updateLocationMarker()
|
||||
textEditor->gotoLine(lineNumber);
|
||||
}
|
||||
|
||||
void DisassemblerAgent::updateBreakpointMarkers()
|
||||
void DisassemblerAgent::removeBreakpointMarker(const Breakpoint &bp)
|
||||
{
|
||||
if (!d->document)
|
||||
return;
|
||||
|
||||
Breakpoints bps = breakHandler()->engineBreakpoints(d->engine);
|
||||
if (bps.isEmpty())
|
||||
return;
|
||||
|
||||
const DisassemblerLines contents = d->contentsAtCurrentLocation();
|
||||
foreach (TextMark *marker, d->breakpointMarks)
|
||||
BreakpointModelId id = bp.id();
|
||||
foreach (DisassemblerBreakpointMarker *marker, d->breakpointMarks) {
|
||||
if (marker->m_bp.id() == id) {
|
||||
d->breakpointMarks.removeOne(marker);
|
||||
d->document->removeMark(marker);
|
||||
qDeleteAll(d->breakpointMarks);
|
||||
d->breakpointMarks.clear();
|
||||
foreach (Breakpoint bp, bps) {
|
||||
delete marker;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DisassemblerAgent::updateBreakpointMarker(const Breakpoint &bp)
|
||||
{
|
||||
removeBreakpointMarker(bp);
|
||||
const quint64 address = bp.response().address;
|
||||
if (!address)
|
||||
continue;
|
||||
int lineNumber = contents.lineForAddress(address);
|
||||
return;
|
||||
|
||||
int lineNumber = d->lineForAddress(address);
|
||||
if (!lineNumber)
|
||||
continue;
|
||||
return;
|
||||
|
||||
// HACK: If it's a FileAndLine breakpoint, and there's a source line
|
||||
// above, move the marker up there. That allows setting and removing
|
||||
@@ -362,13 +393,9 @@ void DisassemblerAgent::updateBreakpointMarkers()
|
||||
--lineNumber;
|
||||
}
|
||||
|
||||
TextMark *marker = new TextMark(QString(), lineNumber,
|
||||
Constants::TEXT_MARK_CATEGORY_BREAKPOINT);
|
||||
marker->setIcon(bp.icon());
|
||||
marker->setPriority(TextMark::NormalPriority);
|
||||
auto marker = new DisassemblerBreakpointMarker(bp, lineNumber);
|
||||
d->breakpointMarks.append(marker);
|
||||
d->document->addMark(marker);
|
||||
}
|
||||
}
|
||||
|
||||
quint64 DisassemblerAgent::address() const
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
namespace Debugger {
|
||||
namespace Internal {
|
||||
|
||||
class Breakpoint;
|
||||
class DebuggerEngine;
|
||||
class DisassemblerAgentPrivate;
|
||||
class DisassemblerLines;
|
||||
@@ -56,7 +57,8 @@ public:
|
||||
void resetLocation();
|
||||
void setContents(const DisassemblerLines &contents);
|
||||
void updateLocationMarker();
|
||||
void updateBreakpointMarkers();
|
||||
void updateBreakpointMarker(const Breakpoint &bp);
|
||||
void removeBreakpointMarker(const Breakpoint &bp);
|
||||
|
||||
// Mimetype: "text/a-asm" or some specialized architecture
|
||||
QString mimeType() const;
|
||||
|
||||
Reference in New Issue
Block a user