Commit a8430f33 authored by hjk's avatar hjk
Browse files

debugger: fix chain of fallbacks for disassembler view.

Use non-mixed mode if source is not available.
parent 3407aab9
......@@ -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;
......
......@@ -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;
};
......
......@@ -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);
......
......@@ -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);
......
......@@ -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();
......
......@@ -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();
......
......@@ -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;
}
......
......@@ -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;
};
......
......@@ -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
......
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