From a8430f3382a0812d46cc975760ea4b567b7eceb6 Mon Sep 17 00:00:00 2001 From: hjk <qtc-committer@nokia.com> Date: Fri, 2 Oct 2009 11:45:19 +0200 Subject: [PATCH] debugger: fix chain of fallbacks for disassembler view. Use non-mixed mode if source is not available. --- src/plugins/debugger/debuggeragents.cpp | 32 +++++++-- src/plugins/debugger/debuggeragents.h | 2 + src/plugins/debugger/debuggermanager.cpp | 6 +- src/plugins/debugger/debuggermanager.h | 3 +- src/plugins/debugger/gdb/gdbengine.cpp | 80 ++++++++++++---------- src/plugins/debugger/gdb/gdbengine.h | 1 + src/plugins/debugger/gdb/trkgdbadapter.cpp | 6 +- src/plugins/debugger/stackframe.h | 8 +-- src/plugins/debugger/stackhandler.cpp | 4 +- 9 files changed, 89 insertions(+), 53 deletions(-) diff --git a/src/plugins/debugger/debuggeragents.cpp b/src/plugins/debugger/debuggeragents.cpp index fbdf2180020..6da7b7c3684 100644 --- a/src/plugins/debugger/debuggeragents.cpp +++ b/src/plugins/debugger/debuggeragents.cpp @@ -43,6 +43,7 @@ #include <utils/qtcassert.h> +#include <QtCore/QDebug> #include <QtGui/QPlainTextEdit> #include <QtGui/QTextCursor> #include <QtGui/QSyntaxHighlighter> @@ -182,7 +183,7 @@ private: */ DisassemblerViewAgent::DisassemblerViewAgent(DebuggerManager *manager) - : QObject(manager), d(new DisassemblerViewAgentPrivate) + : QObject(0), d(new DisassemblerViewAgentPrivate), m_manager(manager) { d->editor = 0; d->locationMark = new LocationMark2(); @@ -212,13 +213,21 @@ void DisassemblerViewAgent::resetLocation() d->editor->markableInterface()->removeMark(d->locationMark); } +QString frameKey(const StackFrame &frame) +{ + return _("%1:%2:%3").arg(frame.function).arg(frame.file).arg(frame.from); +} + void DisassemblerViewAgent::setFrame(const StackFrame &frame) { d->frame = frame; - if (!frame.function.isEmpty()) { - QHash<QString, QString>::ConstIterator it = - d->cache.find(frame.function + frame.file); + if (!frame.function.isEmpty() && frame.function != _("??")) { + QHash<QString, QString>::ConstIterator it = d->cache.find(frameKey(frame)); if (it != d->cache.end()) { + QString msg = QString::fromLatin1("Use cache dissassembler for %1 in %2") + .arg(frame.function).arg(frame.file); + qDebug() << msg; + m_manager->showDebuggerOutput(msg); setContents(*it); return; } @@ -234,7 +243,7 @@ void DisassemblerViewAgent::setContents(const QString &contents) using namespace Core; using namespace TextEditor; - d->cache.insert(d->frame.function + d->frame.file, contents); + d->cache.insert(frameKey(d->frame), contents); QPlainTextEdit *plainTextEdit = 0; EditorManager *editorManager = EditorManager::instance(); if (!d->editor) { @@ -273,6 +282,19 @@ void DisassemblerViewAgent::setContents(const QString &contents) } } +bool DisassemblerViewAgent::contentsCoversAddress(const QString &contents) const +{ + QTC_ASSERT(d, return false); + for (int pos = 0, line = 0; ; ++line, ++pos) { + if (contents.midRef(pos, d->frame.address.size()) == d->frame.address) + return true; + pos = contents.indexOf('\n', pos + 1); + if (pos == -1) + break; + } + return false; +} + QString DisassemblerViewAgent::address() const { return d->frame.address; diff --git a/src/plugins/debugger/debuggeragents.h b/src/plugins/debugger/debuggeragents.h index 0fbe380e9fb..ed3daef9a49 100644 --- a/src/plugins/debugger/debuggeragents.h +++ b/src/plugins/debugger/debuggeragents.h @@ -86,10 +86,12 @@ public: void resetLocation(); Q_SLOT void setContents(const QString &contents); QString address() const; + bool contentsCoversAddress(const QString &contents) const; void cleanup(); private: DisassemblerViewAgentPrivate *d; + DebuggerManager *m_manager; }; diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp index f635bcf71e6..efdb4d9b326 100644 --- a/src/plugins/debugger/debuggermanager.cpp +++ b/src/plugins/debugger/debuggermanager.cpp @@ -1634,14 +1634,14 @@ void DebuggerManager::setState(DebuggerState state) showDebuggerOutput(LogDebug, msg); - resetLocation(); + //resetLocation(); if (state == d->m_state) return; d->m_state = state; - if (d->m_state == InferiorStopped) - resetLocation(); + //if (d->m_state == InferiorStopped) + // resetLocation(); if (d->m_state == DebuggerNotReady) { setBusyCursor(false); diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h index e6dde17f5ed..0cd0ca2aeb0 100644 --- a/src/plugins/debugger/debuggermanager.h +++ b/src/plugins/debugger/debuggermanager.h @@ -228,9 +228,10 @@ public slots: void showStatusMessage(const QString &msg, int timeout = -1); // -1 forever -private slots: +public slots: // FIXME void showDebuggerOutput(const QString &msg) { showDebuggerOutput(LogDebug, msg); } +private slots: void showDebuggerOutput(int channel, const QString &msg); void showDebuggerInput(int channel, const QString &msg); void showApplicationOutput(const QString &data); diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 6aa664c6811..1eaae95ea27 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -967,10 +967,7 @@ void GdbEngine::handleExecRunToFunction(const GdbResponse &response) setState(InferiorStopped); showStatusMessage(tr("Function reached. Stopped.")); GdbMi frame = response.data.findChild("frame"); - StackFrame f; - f.file = QString::fromLocal8Bit(frame.findChild("fullname").data()); - f.line = frame.findChild("line").data().toInt(); - f.address = _(frame.findChild("addr").data()); + StackFrame f = parseStackFrame(frame, 0); gotoLocation(f, true); } @@ -1166,11 +1163,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data) // system="0.00136",start="1218810678.805432",end="1218810678.812011"} setState(InferiorStopped); showStatusMessage(tr("Run to Function finished. Stopped.")); - GdbMi frame = data.findChild("frame"); - StackFrame f; - f.file = QString::fromLocal8Bit(frame.findChild("fullname").data()); - f.line = frame.findChild("line").data().toInt(); - f.address = _(frame.findChild("addr").data()); + StackFrame f = parseStackFrame(data.findChild("frame"), 0); gotoLocation(f, true); #endif } @@ -1288,13 +1281,11 @@ void GdbEngine::handleStop2(const GdbMi &data) } } - // Quick shot - StackFrame f; - f.file = QFile::decodeName(fullName.data()); - f.line = frame.findChild("line").data().toInt(); - f.address = _(frame.findChild("addr").data()); - f.function = _(frame.findChild("func").data()); - gotoLocation(f, true); + // Quick shot: Jump to stack frame #0. + if (frame.isValid()) { + const StackFrame f = parseStackFrame(frame, 0); + gotoLocation(f, true); + } // // Stack @@ -2253,6 +2244,22 @@ void GdbEngine::handleStackSelectThread(const GdbResponse &) } +StackFrame GdbEngine::parseStackFrame(const GdbMi &frameMi, int level) +{ + //qDebug() << "HANDLING FRAME:" << frameMi.toString(); + QStringList files; + files.append(QFile::decodeName(frameMi.findChild("fullname").data())); + files.append(QFile::decodeName(frameMi.findChild("file").data())); + StackFrame frame; + frame.level = level; + frame.file = fullName(files); + frame.function = _(frameMi.findChild("func").data()); + frame.from = _(frameMi.findChild("from").data()); + frame.line = frameMi.findChild("line").data().toInt(); + frame.address = _(frameMi.findChild("addr").data()); + return frame; +} + void GdbEngine::handleStackListFrames(const GdbResponse &response) { #if defined(Q_OS_MAC) @@ -2274,19 +2281,8 @@ void GdbEngine::handleStackListFrames(const GdbResponse &response) int n = stack.childCount(); for (int i = 0; i != n; ++i) { - //qDebug() << "HANDLING FRAME:" << stack.childAt(i).toString(); - const GdbMi frameMi = stack.childAt(i); - StackFrame frame(i); - QStringList files; - files.append(QFile::decodeName(frameMi.findChild("fullname").data())); - files.append(QFile::decodeName(frameMi.findChild("file").data())); - frame.file = fullName(files); - frame.function = _(frameMi.findChild("func").data()); - frame.from = _(frameMi.findChild("from").data()); - frame.line = frameMi.findChild("line").data().toInt(); - frame.address = _(frameMi.findChild("addr").data()); - - stackFrames.append(frame); + stackFrames.append(parseStackFrame(stack.childAt(i), i)); + const StackFrame &frame = stackFrames.back(); #if defined(Q_OS_WIN) const bool isBogus = @@ -3875,18 +3871,18 @@ void GdbEngine::fetchDisassemblerByAddress(DisassemblerViewAgent *agent, QTC_ASSERT(agent, return); bool ok = true; quint64 address = agent->address().toULongLong(&ok, 0); - qDebug() << "ADDRESS: " << agent->address() << address; + //qDebug() << "ADDRESS: " << agent->address() << address; QTC_ASSERT(ok, return); - quint64 start = address - 20; - quint64 end = address + 100; + QString start = QString::number(address - 20, 16); + QString end = QString::number(address + 100, 16); // -data-disassemble [ -s start-addr -e end-addr ] // | [ -f filename -l linenum [ -n lines ] ] -- mode if (useMixedMode) - postCommand(_("-data-disassemble -s %1 -e %2 -- 1").arg(start).arg(end), + postCommand(_("-data-disassemble -s 0x%1 -e 0x%2 -- 1").arg(start).arg(end), Discardable, CB(handleFetchDisassemblerByAddress1), QVariant::fromValue(DisassemblerAgentCookie(agent))); else - postCommand(_("-data-disassemble -s %1 -e %2 -- 0").arg(start).arg(end), + postCommand(_("-data-disassemble -s 0x%1 -e 0x%2 -- 0").arg(start).arg(end), Discardable, CB(handleFetchDisassemblerByAddress0), QVariant::fromValue(DisassemblerAgentCookie(agent))); } @@ -3957,8 +3953,13 @@ void GdbEngine::handleFetchDisassemblerByLine(const GdbResponse &response) if (response.resultClass == GdbResultDone) { GdbMi lines = response.data.findChild("asm_insns"); + if (!lines.children().isEmpty()) + qDebug() << "LINES: " << lines.childAt(0).findChild("line").data(); if (lines.children().isEmpty()) fetchDisassemblerByAddress(ac.agent, true); + else if (lines.children().size() == 1 + && lines.childAt(0).findChild("line").data() == "0") + fetchDisassemblerByAddress(ac.agent, true); else ac.agent->setContents(parseDisassembler(lines)); } else if (response.resultClass == GdbResultError) { @@ -3980,8 +3981,15 @@ void GdbEngine::handleFetchDisassemblerByAddress1(const GdbResponse &response) GdbMi lines = response.data.findChild("asm_insns"); if (lines.children().isEmpty()) fetchDisassemblerByAddress(ac.agent, false); - else - ac.agent->setContents(parseDisassembler(lines)); + else { + QString contents = parseDisassembler(lines); + if (ac.agent->contentsCoversAddress(contents)) { + ac.agent->setContents(parseDisassembler(lines)); + } else { + qDebug() << "FALL BACK TO NON-MIXED"; + fetchDisassemblerByAddress(ac.agent, false); + } + } } else { // 26^error,msg="Cannot access memory at address 0x801ca308" QByteArray msg = response.data.findChild("msg").data(); diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h index e6775a4d406..58352b4ab34 100644 --- a/src/plugins/debugger/gdb/gdbengine.h +++ b/src/plugins/debugger/gdb/gdbengine.h @@ -156,6 +156,7 @@ private: bool supportsThreads() const; void gotoLocation(const StackFrame &frame, bool setLocationMarker); + StackFrame parseStackFrame(const GdbMi &mi, int level); void connectAdapter(); void disconnectAdapter(); diff --git a/src/plugins/debugger/gdb/trkgdbadapter.cpp b/src/plugins/debugger/gdb/trkgdbadapter.cpp index 0d905033032..aec59eaf1f9 100644 --- a/src/plugins/debugger/gdb/trkgdbadapter.cpp +++ b/src/plugins/debugger/gdb/trkgdbadapter.cpp @@ -969,8 +969,10 @@ void TrkGdbAdapter::handleTrkResult(const TrkResult &result) lib.dataseg = dataseg; m_session.libraries.append(lib); logMessage(logMsg); - // This lets gdb trigger a register update etc - sendGdbServerMessage("T05library:;"); + // This lets gdb trigger a register update etc. + // With CS gdb 6.4 we get a non-standard $qfDllInfo#7f+ request + // afterwards, so don't use it for now. + //sendGdbServerMessage("T05library:;"); sendTrkMessage(0x18, TrkCallback(), trkContinueMessage(), "CONTINUE"); break; } diff --git a/src/plugins/debugger/stackframe.h b/src/plugins/debugger/stackframe.h index 8a9f1c2a416..3a0e415e1f2 100644 --- a/src/plugins/debugger/stackframe.h +++ b/src/plugins/debugger/stackframe.h @@ -38,16 +38,16 @@ namespace Internal { struct StackFrame { - StackFrame(int level = 0); + StackFrame(); bool isUsable() const; QString toToolTip() const; QString toString() const; int level; QString function; - QString file; // we try to put an absolute file name in there - QString from; - QString to; + QString file; // We try to put an absolute file name in there. + QString from; // Sometimes something like "/usr/lib/libstdc++.so.6" + QString to; // Used in ScriptEngine only. int line; QString address; }; diff --git a/src/plugins/debugger/stackhandler.cpp b/src/plugins/debugger/stackhandler.cpp index a28fa04399c..e3b25b24334 100644 --- a/src/plugins/debugger/stackhandler.cpp +++ b/src/plugins/debugger/stackhandler.cpp @@ -39,8 +39,8 @@ using namespace Debugger::Internal; -StackFrame::StackFrame(int l) - : level(l), line(0) +StackFrame::StackFrame() + : level(0), line(0) {} bool StackFrame::isUsable() const -- GitLab