Commit 5f38a26c authored by hjk's avatar hjk
Browse files

debugger: fix 'Jump To/Run to' when in instruction-wise mode

parent cd18b3ce
...@@ -172,20 +172,10 @@ struct MemoryViewCookie ...@@ -172,20 +172,10 @@ struct MemoryViewCookie
quint64 length; quint64 length;
}; };
struct SourceLocationCookie
{
explicit SourceLocationCookie(const QString &f = QString(), int l = 0) :
fileName(f), lineNumber(l) {}
QString fileName;
int lineNumber;
};
} // namespace Internal } // namespace Internal
} // namespace Debugger } // namespace Debugger
Q_DECLARE_METATYPE(Debugger::Internal::MemoryViewCookie) Q_DECLARE_METATYPE(Debugger::Internal::MemoryViewCookie)
Q_DECLARE_METATYPE(Debugger::Internal::SourceLocationCookie)
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal {
...@@ -1070,12 +1060,12 @@ void CdbEngine::doInterruptInferior(SpecialStopMode sm) ...@@ -1070,12 +1060,12 @@ void CdbEngine::doInterruptInferior(SpecialStopMode sm)
#endif #endif
} }
void CdbEngine::executeRunToLine(const QString &fileName, int lineNumber) void CdbEngine::executeRunToLine(const ContextData &data)
{ {
// Add one-shot breakpoint // Add one-shot breakpoint
BreakpointParameters bp(BreakpointByFileAndLine); BreakpointParameters bp(BreakpointByFileAndLine);
bp.fileName = fileName; bp.fileName = data.fileName;
bp.lineNumber = lineNumber; bp.lineNumber = data.lineNumber;
postCommand(cdbAddBreakpointCommand(bp, BreakpointId(-1), true), 0); postCommand(cdbAddBreakpointCommand(bp, BreakpointId(-1), true), 0);
continueInferior(); continueInferior();
} }
...@@ -1102,13 +1092,13 @@ void CdbEngine::setRegisterValue(int regnr, const QString &value) ...@@ -1102,13 +1092,13 @@ void CdbEngine::setRegisterValue(int regnr, const QString &value)
reloadRegisters(); reloadRegisters();
} }
void CdbEngine::executeJumpToLine(const QString & fileName, int lineNumber) void CdbEngine::executeJumpToLine(const ContextData &data)
{ {
QByteArray cmd; QByteArray cmd;
ByteArrayInputStream str(cmd); ByteArrayInputStream str(cmd);
// Resolve source line address and go to that location // Resolve source line address and go to that location
str << "? `" << QDir::toNativeSeparators(fileName) << ':' << lineNumber << '`'; str << "? `" << QDir::toNativeSeparators(data.fileName) << ':' << data.lineNumber << '`';
const QVariant cookie = qVariantFromValue(SourceLocationCookie(fileName, lineNumber)); const QVariant cookie = qVariantFromValue(data);
postBuiltinCommand(cmd, 0, &CdbEngine::handleJumpToLineAddressResolution, 0, cookie); postBuiltinCommand(cmd, 0, &CdbEngine::handleJumpToLineAddressResolution, 0, cookie);
} }
...@@ -1123,8 +1113,8 @@ void CdbEngine::handleJumpToLineAddressResolution(const CdbBuiltinCommandPtr &cm ...@@ -1123,8 +1113,8 @@ void CdbEngine::handleJumpToLineAddressResolution(const CdbBuiltinCommandPtr &cm
if (equalPos == -1) if (equalPos == -1)
return; return;
answer.remove(0, equalPos + 3); answer.remove(0, equalPos + 3);
QTC_ASSERT(qVariantCanConvert<SourceLocationCookie>(cmd->cookie), return ; ) QTC_ASSERT(qVariantCanConvert<ContextData>(cmd->cookie), return);
const SourceLocationCookie cookie = qvariant_cast<SourceLocationCookie>(cmd->cookie); const ContextData cookie = qvariant_cast<ContextData>(cmd->cookie);
QByteArray registerCmd; QByteArray registerCmd;
ByteArrayInputStream str(registerCmd); ByteArrayInputStream str(registerCmd);
......
...@@ -108,9 +108,9 @@ public: ...@@ -108,9 +108,9 @@ public:
virtual void continueInferior(); virtual void continueInferior();
virtual void interruptInferior(); virtual void interruptInferior();
virtual void executeRunToLine(const QString &fileName, int lineNumber); virtual void executeRunToLine(const ContextData &data);
virtual void executeRunToFunction(const QString &functionName); virtual void executeRunToFunction(const QString &functionName);
virtual void executeJumpToLine(const QString &fileName, int lineNumber); virtual void executeJumpToLine(const ContextData &data);
virtual void assignValueInDebugger(const WatchData *w, const QString &expr, const QVariant &value); virtual void assignValueInDebugger(const WatchData *w, const QString &expr, const QVariant &value);
virtual void executeDebuggerCommand(const QString &command); virtual void executeDebuggerCommand(const QString &command);
......
...@@ -1458,7 +1458,7 @@ void DebuggerEngine::interruptInferior() ...@@ -1458,7 +1458,7 @@ void DebuggerEngine::interruptInferior()
{ {
} }
void DebuggerEngine::executeRunToLine(const QString &, int) void DebuggerEngine::executeRunToLine(const ContextData &)
{ {
} }
...@@ -1466,7 +1466,7 @@ void DebuggerEngine::executeRunToFunction(const QString &) ...@@ -1466,7 +1466,7 @@ void DebuggerEngine::executeRunToFunction(const QString &)
{ {
} }
void DebuggerEngine::executeJumpToLine(const QString &, int) void DebuggerEngine::executeJumpToLine(const ContextData &)
{ {
} }
......
...@@ -121,6 +121,17 @@ private: ...@@ -121,6 +121,17 @@ private:
quint64 m_address; quint64 m_address;
}; };
class ContextData
{
public:
ContextData() : lineNumber(0), address(0) {}
public:
QString fileName;
int lineNumber;
quint64 address;
};
} // namespace Internal } // namespace Internal
...@@ -323,9 +334,9 @@ protected: ...@@ -323,9 +334,9 @@ protected:
virtual void interruptInferior(); virtual void interruptInferior();
virtual void requestInterruptInferior(); virtual void requestInterruptInferior();
virtual void executeRunToLine(const QString &fileName, int lineNumber); virtual void executeRunToLine(const Internal::ContextData &data);
virtual void executeRunToFunction(const QString &functionName); virtual void executeRunToFunction(const QString &functionName);
virtual void executeJumpToLine(const QString &fileName, int lineNumber); virtual void executeJumpToLine(const Internal::ContextData &data);
virtual void executeDebuggerCommand(const QString &command); virtual void executeDebuggerCommand(const QString &command);
virtual void frameUp(); virtual void frameUp();
...@@ -374,4 +385,6 @@ private: ...@@ -374,4 +385,6 @@ private:
} // namespace Debugger } // namespace Debugger
Q_DECLARE_METATYPE(Debugger::Internal::ContextData)
#endif // DEBUGGER_DEBUGGERENGINE_H #endif // DEBUGGER_DEBUGGERENGINE_H
...@@ -530,22 +530,25 @@ private: ...@@ -530,22 +530,25 @@ private:
// //
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
class ContextData static TextEditor::ITextEditor *currentTextEditor()
{ {
public: if (const Core::EditorManager *editorManager = Core::EditorManager::instance())
ContextData() : lineNumber(0), address(0) {} if (Core::IEditor *editor = editorManager->currentEditor())
return qobject_cast<TextEditor::ITextEditor*>(editor);
public: return 0;
QString fileName; }
int lineNumber;
quint64 address;
};
} // namespace Internal
} // namespace Debugger
Q_DECLARE_METATYPE(Debugger::Internal::ContextData)
static bool currentTextEditorPosition(ContextData *data)
{
if (TextEditor::ITextEditor *textEditor = currentTextEditor()) {
if (const Core::IFile *file = textEditor->file()) {
data->fileName = file->fileName();
data->lineNumber = textEditor->currentLine();
return true;
}
}
return false;
}
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
// //
...@@ -553,9 +556,6 @@ Q_DECLARE_METATYPE(Debugger::Internal::ContextData) ...@@ -553,9 +556,6 @@ Q_DECLARE_METATYPE(Debugger::Internal::ContextData)
// //
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
namespace Debugger {
namespace Internal {
static DebuggerPluginPrivate *theDebuggerCore = 0; static DebuggerPluginPrivate *theDebuggerCore = 0;
/*! /*!
...@@ -817,20 +817,18 @@ public slots: ...@@ -817,20 +817,18 @@ public slots:
{ {
//removeTooltip(); //removeTooltip();
currentEngine()->resetLocation(); currentEngine()->resetLocation();
QString fileName; ContextData data;
int lineNumber; if (currentTextEditorPosition(&data))
if (currentTextEditorPosition(&fileName, &lineNumber)) currentEngine()->executeJumpToLine(data);
currentEngine()->executeJumpToLine(fileName, lineNumber);
} }
void handleExecRunToLine() void handleExecRunToLine()
{ {
//removeTooltip(); //removeTooltip();
currentEngine()->resetLocation(); currentEngine()->resetLocation();
QString fileName; ContextData data;
int lineNumber; if (currentTextEditorPosition(&data))
if (currentTextEditorPosition(&fileName, &lineNumber)) currentEngine()->executeRunToLine(data);
currentEngine()->executeRunToLine(fileName, lineNumber);
} }
void handleExecRunToSelectedFunction() void handleExecRunToSelectedFunction()
...@@ -883,7 +881,7 @@ public slots: ...@@ -883,7 +881,7 @@ public slots:
const QAction *action = qobject_cast<const QAction *>(sender()); const QAction *action = qobject_cast<const QAction *>(sender());
QTC_ASSERT(action, return); QTC_ASSERT(action, return);
const ContextData data = action->data().value<ContextData>(); const ContextData data = action->data().value<ContextData>();
currentEngine()->executeRunToLine(data.fileName, data.lineNumber); currentEngine()->executeRunToLine(data);
} }
void slotJumpToLine() void slotJumpToLine()
...@@ -891,7 +889,7 @@ public slots: ...@@ -891,7 +889,7 @@ public slots:
const QAction *action = qobject_cast<const QAction *>(sender()); const QAction *action = qobject_cast<const QAction *>(sender());
QTC_ASSERT(action, return); QTC_ASSERT(action, return);
const ContextData data = action->data().value<ContextData>(); const ContextData data = action->data().value<ContextData>();
currentEngine()->executeJumpToLine(data.fileName, data.lineNumber); currentEngine()->executeJumpToLine(data);
} }
void handleAddToWatchWindow() void handleAddToWatchWindow()
...@@ -1619,6 +1617,7 @@ void DebuggerPluginPrivate::requestContextMenu(ITextEditor *editor, ...@@ -1619,6 +1617,7 @@ void DebuggerPluginPrivate::requestContextMenu(ITextEditor *editor,
ContextData args; ContextData args;
args.lineNumber = lineNumber; args.lineNumber = lineNumber;
bool contextUsable = true;
BreakpointId id = BreakpointId(); BreakpointId id = BreakpointId();
if (editor->property("DisassemblerView").toBool()) { if (editor->property("DisassemblerView").toBool()) {
...@@ -1631,6 +1630,7 @@ void DebuggerPluginPrivate::requestContextMenu(ITextEditor *editor, ...@@ -1631,6 +1630,7 @@ void DebuggerPluginPrivate::requestContextMenu(ITextEditor *editor,
args.address = needle.address; args.address = needle.address;
needle.lineNumber = -1; needle.lineNumber = -1;
id = breakHandler()->findSimilarBreakpoint(needle); id = breakHandler()->findSimilarBreakpoint(needle);
contextUsable = args.address != 0;
} else { } else {
args.fileName = editor->file()->fileName(); args.fileName = editor->file()->fileName();
id = breakHandler() id = breakHandler()
...@@ -1668,27 +1668,30 @@ void DebuggerPluginPrivate::requestContextMenu(ITextEditor *editor, ...@@ -1668,27 +1668,30 @@ void DebuggerPluginPrivate::requestContextMenu(ITextEditor *editor,
menu->addAction(act); menu->addAction(act);
} else { } else {
// Handle non-existing breakpoint. // Handle non-existing breakpoint.
const QString text = args.address ? const QString text = args.address
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);
QAction *act = new QAction(text, menu); QAction *act = new QAction(text, menu);
act->setData(QVariant::fromValue(args)); act->setData(QVariant::fromValue(args));
act->setEnabled(contextUsable);
connect(act, SIGNAL(triggered()), connect(act, SIGNAL(triggered()),
SLOT(breakpointSetMarginActionTriggered())); SLOT(breakpointSetMarginActionTriggered()));
menu->addAction(act); menu->addAction(act);
} }
// Run to, jump to line below in stopped state. // Run to, jump to line below in stopped state.
if (currentEngine()->state() == InferiorStopOk) { if (currentEngine()->state() == InferiorStopOk && contextUsable) {
menu->addSeparator(); menu->addSeparator();
const QString runText = const QString runText = args.address
DebuggerEngine::tr("Run to Line %1").arg(lineNumber); ? DebuggerEngine::tr("Run to Address 0x%1").arg(args.address, 0, 16)
: DebuggerEngine::tr("Run to Line %1").arg(args.lineNumber);
QAction *runToLineAction = new QAction(runText, menu); QAction *runToLineAction = new QAction(runText, menu);
runToLineAction->setData(QVariant::fromValue(args)); runToLineAction->setData(QVariant::fromValue(args));
connect(runToLineAction, SIGNAL(triggered()), SLOT(slotRunToLine())); connect(runToLineAction, SIGNAL(triggered()), SLOT(slotRunToLine()));
menu->addAction(runToLineAction); menu->addAction(runToLineAction);
if (currentEngine()->debuggerCapabilities() & JumpToLineCapability) { if (currentEngine()->debuggerCapabilities() & JumpToLineCapability) {
const QString jumpText = const QString jumpText = args.address
DebuggerEngine::tr("Jump to Line %1").arg(lineNumber); ? DebuggerEngine::tr("Jump to Address 0x%1").arg(args.address, 0, 16)
: DebuggerEngine::tr("Jump to Line %1").arg(args.lineNumber);
QAction *jumpToLineAction = new QAction(jumpText, menu); QAction *jumpToLineAction = new QAction(jumpText, menu);
menu->addAction(runToLineAction); menu->addAction(runToLineAction);
jumpToLineAction->setData(QVariant::fromValue(args)); jumpToLineAction->setData(QVariant::fromValue(args));
......
...@@ -132,6 +132,7 @@ static bool readStartElement(QXmlStreamReader &r, const char *name) ...@@ -132,6 +132,7 @@ static bool readStartElement(QXmlStreamReader &r, const char *name)
return true; return true;
} }
#if 0
static void debugMode(const QAbstractItemModel *model) static void debugMode(const QAbstractItemModel *model)
{ {
QDebug nospace = qDebug().nospace(); QDebug nospace = qDebug().nospace();
...@@ -139,6 +140,7 @@ static void debugMode(const QAbstractItemModel *model) ...@@ -139,6 +140,7 @@ static void debugMode(const QAbstractItemModel *model)
for (int r = 0; r < model->rowCount(); r++) for (int r = 0; r < model->rowCount(); r++)
nospace << '#' << r << ' ' << model->data(model->index(r, 0)).toString() << '\n'; nospace << '#' << r << ' ' << model->data(model->index(r, 0)).toString() << '\n';
} }
#endif
namespace Debugger { namespace Debugger {
namespace Internal { namespace Internal {
......
...@@ -2015,17 +2015,26 @@ void GdbEngine::executeNextI() ...@@ -2015,17 +2015,26 @@ void GdbEngine::executeNextI()
postCommand("-exec-next-instruction", RunRequest, CB(handleExecuteContinue)); postCommand("-exec-next-instruction", RunRequest, CB(handleExecuteContinue));
} }
void GdbEngine::executeRunToLine(const QString &fileName, int lineNumber) static QByteArray addressSpec(quint64 address)
{
return "*0x" + QByteArray::number(address, 16);
}
void GdbEngine::executeRunToLine(const ContextData &data)
{ {
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
setTokenBarrier(); setTokenBarrier();
notifyInferiorRunRequested(); notifyInferiorRunRequested();
showStatusMessage(tr("Run to line %1 requested...").arg(lineNumber), 5000); showStatusMessage(tr("Run to line %1 requested...").arg(data.lineNumber), 5000);
#if 1 #if 1
m_targetFrame.file = fileName; m_targetFrame.file = data.fileName;
m_targetFrame.line = lineNumber; m_targetFrame.line = data.lineNumber;
QByteArray loc = '"' + breakLocation(fileName).toLocal8Bit() + '"' + ':' QByteArray loc;
+ QByteArray::number(lineNumber); if (data.address)
loc = addressSpec(data.address);
else
loc = '"' + breakLocation(data.fileName).toLocal8Bit() + '"' + ':'
+ QByteArray::number(data.lineNumber);
postCommand("tbreak " + loc); postCommand("tbreak " + loc);
postCommand("continue", RunRequest, CB(handleExecuteRunToLine)); postCommand("continue", RunRequest, CB(handleExecuteRunToLine));
#else #else
...@@ -2046,15 +2055,15 @@ void GdbEngine::executeRunToFunction(const QString &functionName) ...@@ -2046,15 +2055,15 @@ void GdbEngine::executeRunToFunction(const QString &functionName)
continueInferiorInternal(); continueInferiorInternal();
} }
void GdbEngine::executeJumpToLine(const QString &fileName, int lineNumber) void GdbEngine::executeJumpToLine(const ContextData &data)
{ {
QTC_ASSERT(state() == InferiorStopOk, qDebug() << state()); QTC_ASSERT(state() == InferiorStopOk, qDebug() << state());
StackFrame frame; QByteArray loc;
frame.file = fileName; if (data.address)
frame.line = lineNumber; loc = addressSpec(data.address);
#if 1 else
QByteArray loc = '"' + breakLocation(fileName).toLocal8Bit() + '"' + ':' loc = '"' + breakLocation(data.fileName).toLocal8Bit() + '"' + ':'
+ QByteArray::number(lineNumber); + QByteArray::number(data.lineNumber);
postCommand("tbreak " + loc); postCommand("tbreak " + loc);
notifyInferiorRunRequested(); notifyInferiorRunRequested();
postCommand("jump " + loc, RunRequest, CB(handleExecuteJumpToLine)); postCommand("jump " + loc, RunRequest, CB(handleExecuteJumpToLine));
...@@ -2064,15 +2073,6 @@ void GdbEngine::executeJumpToLine(const QString &fileName, int lineNumber) ...@@ -2064,15 +2073,6 @@ void GdbEngine::executeJumpToLine(const QString &fileName, int lineNumber)
// ~"run1 (argc=1, argv=0x7fffbf1f5538) at test1.cpp:242" // ~"run1 (argc=1, argv=0x7fffbf1f5538) at test1.cpp:242"
// ~"242\t x *= 2;" // ~"242\t x *= 2;"
// 23^done" // 23^done"
gotoLocation(frame);
//setBreakpoint();
//postCommand("jump " + loc);
#else
gotoLocation(frame);
setBreakpoint(fileName, lineNumber);
notifyInferiorRunRequested();
postCommand("jump " + loc, RunRequest);
#endif
} }
void GdbEngine::executeReturn() void GdbEngine::executeReturn()
...@@ -2220,11 +2220,6 @@ QString GdbEngine::breakLocation(const QString &file) const ...@@ -2220,11 +2220,6 @@ QString GdbEngine::breakLocation(const QString &file) const
return where; return where;
} }
static QByteArray addressSpec(quint64 address)
{
return "*0x" + QByteArray::number(address, 16);
}
QByteArray GdbEngine::breakpointLocation(BreakpointId id) QByteArray GdbEngine::breakpointLocation(BreakpointId id)
{ {
BreakHandler *handler = breakHandler(); BreakHandler *handler = breakHandler();
......
...@@ -333,9 +333,9 @@ private: ////////// Inferior Management ////////// ...@@ -333,9 +333,9 @@ private: ////////// Inferior Management //////////
void interruptInferior(); void interruptInferior();
void interruptInferiorTemporarily(); void interruptInferiorTemporarily();
void executeRunToLine(const QString &fileName, int lineNumber); void executeRunToLine(const ContextData &data);
void executeRunToFunction(const QString &functionName); void executeRunToFunction(const QString &functionName);
void executeJumpToLine(const QString &fileName, int lineNumber); void executeJumpToLine(const ContextData &data);
void executeReturn(); void executeReturn();
void handleExecuteContinue(const GdbResponse &response); void handleExecuteContinue(const GdbResponse &response);
......
...@@ -285,13 +285,12 @@ void LldbEngineGuest::interruptInferior() ...@@ -285,13 +285,12 @@ void LldbEngineGuest::interruptInferior()
updateThreads(); updateThreads();
} }
void LldbEngineGuest::executeRunToLine(const QString &fileName, int lineNumber) void LldbEngineGuest::executeRunToLine(const ContextData &data);
{ {
DEBUG_FUNC_ENTER; DEBUG_FUNC_ENTER;
// TODO // TODO
Q_UNUSED(fileName); Q_UNUSED(data);
Q_UNUSED(lineNumber);
} }
void LldbEngineGuest::executeRunToFunction(const QString &functionName) void LldbEngineGuest::executeRunToFunction(const QString &functionName)
...@@ -301,13 +300,12 @@ void LldbEngineGuest::executeRunToFunction(const QString &functionName) ...@@ -301,13 +300,12 @@ void LldbEngineGuest::executeRunToFunction(const QString &functionName)
// TODO // TODO
Q_UNUSED(functionName); Q_UNUSED(functionName);
} }
void LldbEngineGuest::executeJumpToLine(const QString &fileName, int lineNumber) void LldbEngineGuest::executeJumpToLine(const ContextData &data);
{ {
DEBUG_FUNC_ENTER; DEBUG_FUNC_ENTER;
// TODO // TODO
Q_UNUSED(fileName); Q_UNUSED(data);
Q_UNUSED(lineNumber);
} }
void LldbEngineGuest::activateFrame(qint64 token) void LldbEngineGuest::activateFrame(qint64 token)
......
...@@ -89,9 +89,9 @@ public: ...@@ -89,9 +89,9 @@ public:
void executeNextI(); void executeNextI();
void continueInferior(); void continueInferior();