Commit 8b226452 authored by hjk's avatar hjk
Browse files

debugger: make breakpoints work in disassembler view

parent aa3cc9f7
......@@ -29,6 +29,7 @@
#include "debuggeragents.h"
#include "breakhandler.h"
#include "debuggerengine.h"
#include "debuggercore.h"
#include "debuggerstringutils.h"
......@@ -191,7 +192,6 @@ void MemoryViewAgent::handleEndOfFileRequested(IEditor *editor)
//
///////////////////////////////////////////////////////////////////////
// Used for the disassembler view
class LocationMark2 : public TextEditor::ITextMark
{
public:
......@@ -204,10 +204,27 @@ public:
void documentClosing() {}
};
class BreakpointMarker2 : public TextEditor::ITextMark
{
public:
BreakpointMarker2(const QIcon &icon) : m_icon(icon) {}
QIcon icon() const { return m_icon; }
void updateLineNumber(int) {}
void updateBlock(const QTextBlock &) {}
void removedFromEditor() {}
void documentClosing() {}
private:
QIcon m_icon;
};
class DisassemblerViewAgentPrivate
{
public:
DisassemblerViewAgentPrivate();
~DisassemblerViewAgentPrivate();
void configureMimeType();
public:
......@@ -216,7 +233,9 @@ public:
bool tryMixed;
bool setMarker;
QPointer<DebuggerEngine> engine;
LocationMark2 *locationMark;
TextEditor::ITextMark *locationMark;
QList<TextEditor::ITextMark *> breakpointMarks;
QHash<QString, DisassemblerLines> cache;
QString mimeType;
};
......@@ -230,6 +249,15 @@ DisassemblerViewAgentPrivate::DisassemblerViewAgentPrivate()
{
}
DisassemblerViewAgentPrivate::~DisassemblerViewAgentPrivate()
{
if (editor) {
EditorManager *editorManager = EditorManager::instance();
editorManager->closeEditors(QList<IEditor *>() << editor);
}
editor = 0;
delete locationMark;
}
/*!
\class DisassemblerViewAgent
......@@ -247,12 +275,6 @@ DisassemblerViewAgent::DisassemblerViewAgent(DebuggerEngine *engine)
DisassemblerViewAgent::~DisassemblerViewAgent()
{
EditorManager *editorManager = EditorManager::instance();
if (d->editor)
editorManager->closeEditors(QList<IEditor *>() << d->editor);
d->editor = 0;
delete d->locationMark;
d->locationMark = 0;
delete d;
d = 0;
}
......@@ -264,8 +286,9 @@ void DisassemblerViewAgent::cleanup()
void DisassemblerViewAgent::resetLocation()
{
if (d->editor)
d->editor->markableInterface()->removeMark(d->locationMark);
if (!d->editor)
return;
d->editor->markableInterface()->removeMark(d->locationMark);
}
QString frameKey(const StackFrame &frame)
......@@ -286,11 +309,10 @@ bool DisassemblerViewAgent::isMixed() const
&& d->frame.function != _("??");
}
void DisassemblerViewAgent::setFrame(const StackFrame &frame, bool tryMixed,
bool setMarker)
void DisassemblerViewAgent::setFrame(const StackFrame &frame,
bool tryMixed, bool setMarker)
{
d->frame = frame;
d->setMarker = setMarker;
d->tryMixed = tryMixed;
if (isMixed()) {
QHash<QString, DisassemblerLines>::ConstIterator it =
......@@ -300,6 +322,8 @@ void DisassemblerViewAgent::setFrame(const StackFrame &frame, bool tryMixed,
.arg(frame.function).arg(frame.file);
d->engine->showMessage(msg);
setContents(*it);
updateBreakpointMarkers();
updateLocationMarker();
return;
}
}
......@@ -384,21 +408,61 @@ void DisassemblerViewAgent::setContents(const DisassemblerLines &contents)
plainTextEdit->setPlainText(str);
plainTextEdit->setReadOnly(true);
if (d->setMarker)
d->editor->markableInterface()->removeMark(d->locationMark);
d->editor->setDisplayName(_("Disassembler (%1)").arg(d->frame.function));
d->cache.insert(frameKey(d->frame), contents);
d->editor->setDisplayName(_("Disassembler (%1)").arg(d->frame.function));
updateBreakpointMarkers();
updateLocationMarker();
}
void DisassemblerViewAgent::updateLocationMarker()
{
QTC_ASSERT(d->editor, return);
const DisassemblerLines &contents = d->cache.value(frameKey(d->frame));
int lineNumber = contents.lineForAddress(d->frame.address);
if (lineNumber && d->setMarker)
d->editor->markableInterface()->addMark(d->locationMark, lineNumber);
if (d->setMarker) {
d->editor->markableInterface()->removeMark(d->locationMark);
if (lineNumber)
d->editor->markableInterface()->addMark(d->locationMark, lineNumber);
}
QPlainTextEdit *plainTextEdit =
qobject_cast<QPlainTextEdit *>(d->editor->widget());
QTC_ASSERT(plainTextEdit, return);
QTextCursor tc = plainTextEdit->textCursor();
QTextBlock block = tc.document()->findBlockByNumber(lineNumber - 1);
tc.setPosition(block.position());
plainTextEdit->setTextCursor(tc);
}
void DisassemblerViewAgent::updateBreakpointMarkers()
{
if (!d->editor)
return;
BreakHandler *handler = breakHandler();
BreakpointIds ids = handler->engineBreakpointIds(d->engine);
if (ids.isEmpty())
return;
const DisassemblerLines &contents = d->cache.value(frameKey(d->frame));
foreach (TextEditor::ITextMark *marker, d->breakpointMarks)
d->editor->markableInterface()->removeMark(marker);
d->breakpointMarks.clear();
foreach (BreakpointId id, ids) {
const quint64 address = handler->address(id);
if (!address)
continue;
const int lineNumber = contents.lineForAddress(address);
BreakpointMarker2 *marker = new BreakpointMarker2(handler->icon(id));
d->breakpointMarks.append(marker);
d->editor->markableInterface()->addMark(marker, lineNumber);
}
}
quint64 DisassemblerViewAgent::address() const
{
return d->frame.address;
......
......@@ -91,6 +91,8 @@ public:
const StackFrame &frame() const;
void resetLocation();
void setContents(const DisassemblerLines &contents);
void updateLocationMarker();
void updateBreakpointMarkers();
// Mimetype: "text/a-asm" or some specialized architecture
QString mimeType() const;
......
......@@ -1217,6 +1217,7 @@ void DebuggerEngine::attemptBreakpointSynchronization()
handler->setEngine(id, this);
}
bool done = true;
foreach (BreakpointId id, handler->engineBreakpointIds(this)) {
switch (handler->state(id)) {
case BreakpointNew:
......@@ -1224,17 +1225,21 @@ void DebuggerEngine::attemptBreakpointSynchronization()
QTC_ASSERT(false, /**/);
continue;
case BreakpointInsertRequested:
done = false;
insertBreakpoint(id);
continue;
case BreakpointChangeRequested:
done = false;
changeBreakpoint(id);
continue;
case BreakpointRemoveRequested:
done = false;
removeBreakpoint(id);
continue;
case BreakpointChangeProceeding:
case BreakpointInsertProceeding:
case BreakpointRemoveProceeding:
done = false;
//qDebug() << "BREAKPOINT " << id << " STILL IN PROGRESS, STATE"
// << handler->state(id);
continue;
......@@ -1249,6 +1254,8 @@ void DebuggerEngine::attemptBreakpointSynchronization()
QTC_ASSERT(false, qDebug() << "UNKNOWN STATE" << id << state());
}
if (done)
d->m_disassemblerViewAgent.updateBreakpointMarkers();
}
bool DebuggerEngine::acceptsBreakpoint(BreakpointId) const
......
......@@ -2855,9 +2855,9 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine)
#endif
m_startRemoteAction->setEnabled(true);
const bool isCore = engine->startParameters().startMode == AttachCore;
const bool stopped = m_state == InferiorStopOk;
const bool detachable = stopped
&& engine->startParameters().startMode != AttachCore;
const bool detachable = stopped && !isCore;
m_detachAction->setEnabled(detachable);
if (stopped)
......@@ -2873,7 +2873,7 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine)
m_actions.breakAction->setEnabled(true);
//m_actions.snapshotAction->setEnabled(stopped && (caps & SnapshotCapability));
action(OperateByInstruction)->setEnabled(stopped);
action(OperateByInstruction)->setEnabled(stopped || isCore);
m_actions.resetAction->setEnabled(m_state != DebuggerNotReady
&& m_state != DebuggerFinished);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment