forked from qt-creator/qt-creator
Debugger: Recognize source data within disassembler view
... and use it to toggle breakpoints by file and line, and for jumping to file and line. Task-number: QTCREATORBUG-14278 Change-Id: I799d085eb53339905ea3608022aeae5a9aef1fda Reviewed-by: Niels Weber <niels.weber@theqtcompany.com> Reviewed-by: Christian Stenger <christian.stenger@theqtcompany.com>
This commit is contained in:
@@ -150,8 +150,11 @@ bool LocationMark::isDraggable() const
|
|||||||
void LocationMark::dragToLine(int line)
|
void LocationMark::dragToLine(int line)
|
||||||
{
|
{
|
||||||
if (m_engine) {
|
if (m_engine) {
|
||||||
if (BaseTextEditor *textEditor = BaseTextEditor::currentTextEditor())
|
if (BaseTextEditor *textEditor = BaseTextEditor::currentTextEditor()) {
|
||||||
m_engine->executeJumpToLine(getLocationContext(textEditor->textDocument(), line));
|
ContextData location = getLocationContext(textEditor->textDocument(), line);
|
||||||
|
if (location.isValid())
|
||||||
|
m_engine->executeJumpToLine(location);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -170,15 +170,18 @@ private:
|
|||||||
quint64 m_address;
|
quint64 m_address;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum LocationType { UnknownLocation, LocationByFile, LocationByAddress };
|
||||||
|
|
||||||
class ContextData
|
class ContextData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ContextData() : lineNumber(0), address(0) {}
|
bool isValid() const { return type != UnknownLocation; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
LocationType type = UnknownLocation;
|
||||||
QString fileName;
|
QString fileName;
|
||||||
int lineNumber;
|
int lineNumber = 0;
|
||||||
quint64 address;
|
quint64 address = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DebuggerEngine : public QObject
|
class DebuggerEngine : public QObject
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ namespace Internal {
|
|||||||
|
|
||||||
const char OPENED_BY_DEBUGGER[] = "OpenedByDebugger";
|
const char OPENED_BY_DEBUGGER[] = "OpenedByDebugger";
|
||||||
const char OPENED_WITH_DISASSEMBLY[] = "DisassemblerView";
|
const char OPENED_WITH_DISASSEMBLY[] = "DisassemblerView";
|
||||||
|
const char DISASSEMBLER_SOURCE_FILE[] = "DisassemblerSourceFile";
|
||||||
|
|
||||||
// Debug action
|
// Debug action
|
||||||
const char DEBUG[] = "Debugger.Debug";
|
const char DEBUG[] = "Debugger.Debug";
|
||||||
|
|||||||
@@ -618,7 +618,7 @@ public:
|
|||||||
{
|
{
|
||||||
QString message;
|
QString message;
|
||||||
if (isMessageOnly) {
|
if (isMessageOnly) {
|
||||||
if (data.address) {
|
if (data.type == LocationByAddress) {
|
||||||
//: Message tracepoint: Address hit.
|
//: Message tracepoint: Address hit.
|
||||||
message = tr("0x%1 hit").arg(data.address, 0, 16);
|
message = tr("0x%1 hit").arg(data.address, 0, 16);
|
||||||
} else {
|
} else {
|
||||||
@@ -638,10 +638,7 @@ public:
|
|||||||
return;
|
return;
|
||||||
message = dialog.textValue();
|
message = dialog.textValue();
|
||||||
}
|
}
|
||||||
if (data.address)
|
toggleBreakpoint(data, message);
|
||||||
toggleBreakpointByAddress(data.address, message);
|
|
||||||
else
|
|
||||||
toggleBreakpointByFileAndLine(data.fileName, data.lineNumber, message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateWatchersHeader(int section, int, int newSize)
|
void updateWatchersHeader(int section, int, int newSize)
|
||||||
@@ -687,11 +684,8 @@ public:
|
|||||||
|
|
||||||
void activatePreviousMode();
|
void activatePreviousMode();
|
||||||
void activateDebugMode();
|
void activateDebugMode();
|
||||||
void toggleBreakpoint();
|
void toggleBreakpointHelper();
|
||||||
void toggleBreakpointByFileAndLine(const QString &fileName, int lineNumber,
|
void toggleBreakpoint(const ContextData &location, const QString &tracePointMessage = QString());
|
||||||
const QString &tracePointMessage = QString());
|
|
||||||
void toggleBreakpointByAddress(quint64 address,
|
|
||||||
const QString &tracePointMessage = QString());
|
|
||||||
void onModeChanged(IMode *mode);
|
void onModeChanged(IMode *mode);
|
||||||
void onCoreAboutToOpen();
|
void onCoreAboutToOpen();
|
||||||
void updateDebugWithoutDeployMenu();
|
void updateDebugWithoutDeployMenu();
|
||||||
@@ -829,17 +823,23 @@ public slots:
|
|||||||
void handleExecJumpToLine()
|
void handleExecJumpToLine()
|
||||||
{
|
{
|
||||||
currentEngine()->resetLocation();
|
currentEngine()->resetLocation();
|
||||||
if (BaseTextEditor *textEditor = BaseTextEditor::currentTextEditor())
|
if (BaseTextEditor *textEditor = BaseTextEditor::currentTextEditor()) {
|
||||||
currentEngine()->executeJumpToLine(getLocationContext(textEditor->textDocument(),
|
ContextData location = getLocationContext(textEditor->textDocument(),
|
||||||
textEditor->currentLine()));
|
textEditor->currentLine());
|
||||||
|
if (location.isValid())
|
||||||
|
currentEngine()->executeJumpToLine(location);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleExecRunToLine()
|
void handleExecRunToLine()
|
||||||
{
|
{
|
||||||
currentEngine()->resetLocation();
|
currentEngine()->resetLocation();
|
||||||
if (BaseTextEditor *textEditor = BaseTextEditor::currentTextEditor())
|
if (BaseTextEditor *textEditor = BaseTextEditor::currentTextEditor()) {
|
||||||
currentEngine()->executeRunToLine(getLocationContext(textEditor->textDocument(),
|
ContextData location = getLocationContext(textEditor->textDocument(),
|
||||||
textEditor->currentLine()));
|
textEditor->currentLine());
|
||||||
|
if (location.isValid())
|
||||||
|
currentEngine()->executeRunToLine(location);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleExecRunToSelectedFunction()
|
void handleExecRunToSelectedFunction()
|
||||||
@@ -1573,26 +1573,18 @@ void DebuggerPluginPrivate::updateBreakMenuItem(IEditor *editor)
|
|||||||
void DebuggerPluginPrivate::requestContextMenu(TextEditorWidget *widget,
|
void DebuggerPluginPrivate::requestContextMenu(TextEditorWidget *widget,
|
||||||
int lineNumber, QMenu *menu)
|
int lineNumber, QMenu *menu)
|
||||||
{
|
{
|
||||||
ContextData args;
|
|
||||||
args.lineNumber = lineNumber;
|
|
||||||
bool contextUsable = true;
|
|
||||||
|
|
||||||
Breakpoint bp;
|
Breakpoint bp;
|
||||||
TextDocument *document = widget->textDocument();
|
TextDocument *document = widget->textDocument();
|
||||||
args.fileName = document->filePath().toString();
|
|
||||||
if (document->property(Constants::OPENED_WITH_DISASSEMBLY).toBool()) {
|
ContextData args = getLocationContext(document, lineNumber);
|
||||||
QString line = document->plainText()
|
if (args.type == LocationByAddress) {
|
||||||
.section(QLatin1Char('\n'), lineNumber - 1, lineNumber - 1);
|
|
||||||
BreakpointResponse needle;
|
BreakpointResponse needle;
|
||||||
needle.type = BreakpointByAddress;
|
needle.type = BreakpointByAddress;
|
||||||
needle.address = DisassemblerLine::addressFromDisassemblyLine(line);
|
needle.address = args.address;
|
||||||
args.address = needle.address;
|
|
||||||
needle.lineNumber = -1;
|
needle.lineNumber = -1;
|
||||||
bp = breakHandler()->findSimilarBreakpoint(needle);
|
bp = breakHandler()->findSimilarBreakpoint(needle);
|
||||||
contextUsable = args.address != 0;
|
} else if (args.type == LocationByFile) {
|
||||||
} else {
|
bp = breakHandler()->findBreakpointByFileAndLine(args.fileName, lineNumber);
|
||||||
bp = breakHandler()
|
|
||||||
->findBreakpointByFileAndLine(args.fileName, lineNumber);
|
|
||||||
if (!bp)
|
if (!bp)
|
||||||
bp = breakHandler()->findBreakpointByFileAndLine(args.fileName, lineNumber, false);
|
bp = breakHandler()->findBreakpointByFileAndLine(args.fileName, lineNumber, false);
|
||||||
}
|
}
|
||||||
@@ -1625,7 +1617,7 @@ void DebuggerPluginPrivate::requestContextMenu(TextEditorWidget *widget,
|
|||||||
? tr("Set Breakpoint at 0x%1").arg(args.address, 0, 16)
|
? tr("Set Breakpoint at 0x%1").arg(args.address, 0, 16)
|
||||||
: tr("Set Breakpoint at Line %1").arg(lineNumber);
|
: tr("Set Breakpoint at Line %1").arg(lineNumber);
|
||||||
auto act = menu->addAction(text);
|
auto act = menu->addAction(text);
|
||||||
act->setEnabled(contextUsable);
|
act->setEnabled(args.isValid());
|
||||||
connect(act, &QAction::triggered, [this, args] {
|
connect(act, &QAction::triggered, [this, args] {
|
||||||
breakpointSetMarginActionTriggered(false, args);
|
breakpointSetMarginActionTriggered(false, args);
|
||||||
});
|
});
|
||||||
@@ -1635,14 +1627,14 @@ void DebuggerPluginPrivate::requestContextMenu(TextEditorWidget *widget,
|
|||||||
? tr("Set Message Tracepoint at 0x%1...").arg(args.address, 0, 16)
|
? tr("Set Message Tracepoint at 0x%1...").arg(args.address, 0, 16)
|
||||||
: tr("Set Message Tracepoint at Line %1...").arg(lineNumber);
|
: tr("Set Message Tracepoint at Line %1...").arg(lineNumber);
|
||||||
act = menu->addAction(tracePointText);
|
act = menu->addAction(tracePointText);
|
||||||
act->setEnabled(contextUsable);
|
act->setEnabled(args.isValid());
|
||||||
connect(act, &QAction::triggered, [this, args] {
|
connect(act, &QAction::triggered, [this, args] {
|
||||||
breakpointSetMarginActionTriggered(true, args);
|
breakpointSetMarginActionTriggered(true, args);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run to, jump to line below in stopped state.
|
// Run to, jump to line below in stopped state.
|
||||||
if (currentEngine()->state() == InferiorStopOk && contextUsable) {
|
if (currentEngine()->state() == InferiorStopOk && args.isValid()) {
|
||||||
menu->addSeparator();
|
menu->addSeparator();
|
||||||
if (currentEngine()->hasCapability(RunToLineCapability)) {
|
if (currentEngine()->hasCapability(RunToLineCapability)) {
|
||||||
auto act = menu->addAction(args.address
|
auto act = menu->addAction(args.address
|
||||||
@@ -1678,72 +1670,58 @@ void DebuggerPluginPrivate::requestContextMenu(TextEditorWidget *widget,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerPluginPrivate::toggleBreakpoint()
|
void DebuggerPluginPrivate::toggleBreakpoint(const ContextData &location, const QString &tracePointMessage)
|
||||||
{
|
|
||||||
BaseTextEditor *textEditor = BaseTextEditor::currentTextEditor();
|
|
||||||
QTC_ASSERT(textEditor, return);
|
|
||||||
const int lineNumber = textEditor->currentLine();
|
|
||||||
if (textEditor->property(Constants::OPENED_WITH_DISASSEMBLY).toBool()) {
|
|
||||||
QString line = textEditor->textDocument()->plainText()
|
|
||||||
.section(QLatin1Char('\n'), lineNumber - 1, lineNumber - 1);
|
|
||||||
quint64 address = DisassemblerLine::addressFromDisassemblyLine(line);
|
|
||||||
toggleBreakpointByAddress(address);
|
|
||||||
} else if (lineNumber >= 0) {
|
|
||||||
toggleBreakpointByFileAndLine(textEditor->document()->filePath().toString(), lineNumber);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebuggerPluginPrivate::toggleBreakpointByFileAndLine(const QString &fileName,
|
|
||||||
int lineNumber, const QString &tracePointMessage)
|
|
||||||
{
|
{
|
||||||
|
QTC_ASSERT(location.isValid(), return);
|
||||||
BreakHandler *handler = m_breakHandler;
|
BreakHandler *handler = m_breakHandler;
|
||||||
Breakpoint bp = handler->findBreakpointByFileAndLine(fileName, lineNumber, true);
|
Breakpoint bp;
|
||||||
|
if (location.type == LocationByFile) {
|
||||||
|
bp = handler->findBreakpointByFileAndLine(location.fileName, location.lineNumber, true);
|
||||||
if (!bp)
|
if (!bp)
|
||||||
bp = handler->findBreakpointByFileAndLine(fileName, lineNumber, false);
|
bp = handler->findBreakpointByFileAndLine(location.fileName, location.lineNumber, false);
|
||||||
|
} else if (location.type == LocationByAddress) {
|
||||||
|
bp = handler->findBreakpointByAddress(location.address);
|
||||||
|
}
|
||||||
|
|
||||||
if (bp) {
|
if (bp) {
|
||||||
bp.removeBreakpoint();
|
bp.removeBreakpoint();
|
||||||
} else {
|
} else {
|
||||||
BreakpointParameters data(BreakpointByFileAndLine);
|
BreakpointParameters data;
|
||||||
|
if (location.type == LocationByFile) {
|
||||||
|
data.type = BreakpointByFileAndLine;
|
||||||
if (boolSetting(BreakpointsFullPathByDefault))
|
if (boolSetting(BreakpointsFullPathByDefault))
|
||||||
data.pathUsage = BreakpointUseFullPath;
|
data.pathUsage = BreakpointUseFullPath;
|
||||||
data.tracepoint = !tracePointMessage.isEmpty();
|
data.tracepoint = !tracePointMessage.isEmpty();
|
||||||
data.message = tracePointMessage;
|
data.message = tracePointMessage;
|
||||||
data.fileName = fileName;
|
data.fileName = location.fileName;
|
||||||
data.lineNumber = lineNumber;
|
data.lineNumber = location.lineNumber;
|
||||||
|
} else if (location.type == LocationByAddress) {
|
||||||
|
data.type = BreakpointByAddress;
|
||||||
|
data.tracepoint = !tracePointMessage.isEmpty();
|
||||||
|
data.message = tracePointMessage;
|
||||||
|
data.address = location.address;
|
||||||
|
}
|
||||||
handler->appendBreakpoint(data);
|
handler->appendBreakpoint(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerPluginPrivate::toggleBreakpointByAddress(quint64 address,
|
void DebuggerPluginPrivate::toggleBreakpointHelper()
|
||||||
const QString &tracePointMessage)
|
|
||||||
{
|
{
|
||||||
BreakHandler *handler = m_breakHandler;
|
BaseTextEditor *textEditor = BaseTextEditor::currentTextEditor();
|
||||||
if (Breakpoint bp = handler->findBreakpointByAddress(address)) {
|
QTC_ASSERT(textEditor, return);
|
||||||
bp.removeBreakpoint();
|
const int lineNumber = textEditor->currentLine();
|
||||||
} else {
|
ContextData location = getLocationContext(textEditor->textDocument(), lineNumber);
|
||||||
BreakpointParameters data(BreakpointByAddress);
|
if (location.isValid())
|
||||||
data.tracepoint = !tracePointMessage.isEmpty();
|
toggleBreakpoint(location);
|
||||||
data.message = tracePointMessage;
|
|
||||||
data.address = address;
|
|
||||||
handler->appendBreakpoint(data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerPluginPrivate::requestMark(TextEditorWidget *widget, int lineNumber,
|
void DebuggerPluginPrivate::requestMark(TextEditorWidget *widget, int lineNumber,
|
||||||
TextMarkRequestKind kind)
|
TextMarkRequestKind kind)
|
||||||
{
|
{
|
||||||
if (kind != BreakpointRequest)
|
if (kind == BreakpointRequest) {
|
||||||
return;
|
ContextData location = getLocationContext(widget->textDocument(), lineNumber);
|
||||||
|
if (location.isValid())
|
||||||
TextDocument *document = widget->textDocument();
|
toggleBreakpoint(location);
|
||||||
if (document->property(Constants::OPENED_WITH_DISASSEMBLY).toBool()) {
|
|
||||||
QString line = document->plainText()
|
|
||||||
.section(QLatin1Char('\n'), lineNumber - 1, lineNumber - 1);
|
|
||||||
quint64 address = DisassemblerLine::addressFromDisassemblyLine(line);
|
|
||||||
toggleBreakpointByAddress(address);
|
|
||||||
} else {
|
|
||||||
toggleBreakpointByFileAndLine(document->filePath().toString(), lineNumber);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2801,7 +2779,7 @@ void DebuggerPluginPrivate::extensionsInitialized()
|
|||||||
cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("F8") : tr("F9")));
|
cmd->setDefaultKeySequence(QKeySequence(UseMacShortcuts ? tr("F8") : tr("F9")));
|
||||||
debugMenu->addAction(cmd);
|
debugMenu->addAction(cmd);
|
||||||
connect(m_breakAction, &QAction::triggered,
|
connect(m_breakAction, &QAction::triggered,
|
||||||
this, &DebuggerPluginPrivate::toggleBreakpoint);
|
this, &DebuggerPluginPrivate::toggleBreakpointHelper);
|
||||||
|
|
||||||
debugMenu->addSeparator();
|
debugMenu->addSeparator();
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
#include "debuggerstartparameters.h"
|
#include "debuggerstartparameters.h"
|
||||||
#include "debuggerstringutils.h"
|
#include "debuggerstringutils.h"
|
||||||
#include "disassemblerlines.h"
|
#include "disassemblerlines.h"
|
||||||
|
#include "sourceutils.h"
|
||||||
|
|
||||||
#include <coreplugin/coreconstants.h>
|
#include <coreplugin/coreconstants.h>
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
@@ -292,10 +293,13 @@ void DisassemblerAgent::setContentsToDocument(const DisassemblerLines &contents)
|
|||||||
widget->setReadOnly(true);
|
widget->setReadOnly(true);
|
||||||
widget->setRequestMarkEnabled(true);
|
widget->setRequestMarkEnabled(true);
|
||||||
}
|
}
|
||||||
|
// FIXME: This is accumulating quite a bit out-of-band data.
|
||||||
|
// Make that a proper TextDocument reimplementation.
|
||||||
d->document = qobject_cast<TextDocument *>(editor->document());
|
d->document = qobject_cast<TextDocument *>(editor->document());
|
||||||
QTC_ASSERT(d->document, return);
|
QTC_ASSERT(d->document, return);
|
||||||
d->document->setProperty(Debugger::Constants::OPENED_BY_DEBUGGER, true);
|
d->document->setProperty(Debugger::Constants::OPENED_BY_DEBUGGER, true);
|
||||||
d->document->setProperty(Debugger::Constants::OPENED_WITH_DISASSEMBLY, true);
|
d->document->setProperty(Debugger::Constants::OPENED_WITH_DISASSEMBLY, true);
|
||||||
|
d->document->setProperty(Debugger::Constants::DISASSEMBLER_SOURCE_FILE, d->location.fileName());
|
||||||
d->configureMimeType();
|
d->configureMimeType();
|
||||||
} else {
|
} else {
|
||||||
EditorManager::activateEditorForDocument(d->document);
|
EditorManager::activateEditorForDocument(d->document);
|
||||||
@@ -345,9 +349,19 @@ void DisassemblerAgent::updateBreakpointMarkers()
|
|||||||
const quint64 address = bp.response().address;
|
const quint64 address = bp.response().address;
|
||||||
if (!address)
|
if (!address)
|
||||||
continue;
|
continue;
|
||||||
const int lineNumber = contents.lineForAddress(address);
|
int lineNumber = contents.lineForAddress(address);
|
||||||
if (!lineNumber)
|
if (!lineNumber)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// HACK: If it's a FileAndLine breakpoint, and there's a source line
|
||||||
|
// above, move the marker up there. That allows setting and removing
|
||||||
|
// normal breakpoints from within the disassembler view.
|
||||||
|
if (bp.type() == BreakpointByFileAndLine) {
|
||||||
|
ContextData context = getLocationContext(d->document, lineNumber - 1);
|
||||||
|
if (context.type == LocationByFile)
|
||||||
|
--lineNumber;
|
||||||
|
}
|
||||||
|
|
||||||
TextMark *marker = new TextMark(QString(), lineNumber,
|
TextMark *marker = new TextMark(QString(), lineNumber,
|
||||||
Constants::TEXT_MARK_CATEGORY_BREAKPOINT);
|
Constants::TEXT_MARK_CATEGORY_BREAKPOINT);
|
||||||
marker->setIcon(bp.icon());
|
marker->setIcon(bp.icon());
|
||||||
|
|||||||
@@ -29,7 +29,9 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "disassemblerlines.h"
|
#include "disassemblerlines.h"
|
||||||
|
#include "debuggerengine.h"
|
||||||
#include "debuggerstringutils.h"
|
#include "debuggerstringutils.h"
|
||||||
|
#include "sourceutils.h"
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
@@ -72,13 +74,6 @@ void DisassemblerLine::fromString(const QString &unparsed)
|
|||||||
data = unparsed;
|
data = unparsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
quint64 DisassemblerLine::addressFromDisassemblyLine(const QString &line)
|
|
||||||
{
|
|
||||||
DisassemblerLine l;
|
|
||||||
l.fromString(line);
|
|
||||||
return l.address;
|
|
||||||
}
|
|
||||||
|
|
||||||
quint64 DisassemblerLines::startAddress() const
|
quint64 DisassemblerLines::startAddress() const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < m_data.size(); ++i)
|
for (int i = 0; i < m_data.size(); ++i)
|
||||||
|
|||||||
@@ -53,9 +53,6 @@ public:
|
|||||||
QString toString(int maxOp = 0) const;
|
QString toString(int maxOp = 0) const;
|
||||||
void fromString(const QString &unparsed);
|
void fromString(const QString &unparsed);
|
||||||
|
|
||||||
// Return address of an assembly line "0x0dfd bla".
|
|
||||||
static quint64 addressFromDisassemblyLine(const QString &line);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
quint64 address; // (ass) Address of instruction in memory/in binary.
|
quint64 address; // (ass) Address of instruction in memory/in binary.
|
||||||
QString function; // (ass) Function to which current instruction belongs.
|
QString function; // (ass) Function to which current instruction belongs.
|
||||||
|
|||||||
@@ -48,6 +48,8 @@
|
|||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QTextDocument>
|
||||||
|
#include <QTextBlock>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -340,11 +342,29 @@ ContextData getLocationContext(TextDocument *document, int lineNumber)
|
|||||||
{
|
{
|
||||||
ContextData data;
|
ContextData data;
|
||||||
QTC_ASSERT(document, return data);
|
QTC_ASSERT(document, return data);
|
||||||
data.fileName = document->filePath().toString();
|
|
||||||
if (document->property(Constants::OPENED_WITH_DISASSEMBLY).toBool()) {
|
if (document->property(Constants::OPENED_WITH_DISASSEMBLY).toBool()) {
|
||||||
QString line = document->plainText().section(QLatin1Char('\n'), lineNumber - 1, lineNumber - 1);
|
QString line = document->document()->findBlockByNumber(lineNumber - 1).text();
|
||||||
data.address = DisassemblerLine::addressFromDisassemblyLine(line);
|
DisassemblerLine l;
|
||||||
|
l.fromString(line);
|
||||||
|
if (l.address) {
|
||||||
|
data.type = LocationByAddress;
|
||||||
|
data.address = l.address;
|
||||||
} else {
|
} else {
|
||||||
|
QString fileName = document->property(Constants::DISASSEMBLER_SOURCE_FILE).toString();
|
||||||
|
if (!fileName.isEmpty()) {
|
||||||
|
// Possibly one of the "27 [1] foo = x" lines
|
||||||
|
int pos = line.indexOf(QLatin1Char('['));
|
||||||
|
int ln = line.left(pos - 1).toInt();
|
||||||
|
if (ln > 0) {
|
||||||
|
data.type = LocationByFile;
|
||||||
|
data.fileName = fileName;
|
||||||
|
data.lineNumber = ln;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
data.type = LocationByFile;
|
||||||
|
data.fileName = document->filePath().toString();
|
||||||
data.lineNumber = lineNumber;
|
data.lineNumber = lineNumber;
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
|
|||||||
Reference in New Issue
Block a user