forked from qt-creator/qt-creator
debugger: add a simple syntax highlighter for disassembler output
This commit is contained in:
@@ -44,6 +44,7 @@
|
|||||||
|
|
||||||
#include <QtGui/QPlainTextEdit>
|
#include <QtGui/QPlainTextEdit>
|
||||||
#include <QtGui/QTextCursor>
|
#include <QtGui/QTextCursor>
|
||||||
|
#include <QtGui/QSyntaxHighlighter>
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
@@ -143,6 +144,30 @@ struct DisassemblerViewAgentPrivate
|
|||||||
LocationMark2 *locationMark;
|
LocationMark2 *locationMark;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\class DisassemblerSyntaxHighlighter
|
||||||
|
|
||||||
|
Simple syntax highlighter to make the disassembler text less prominent.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class DisassemblerHighlighter : public QSyntaxHighlighter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DisassemblerHighlighter(QPlainTextEdit *parent)
|
||||||
|
: QSyntaxHighlighter(parent->document())
|
||||||
|
{}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void highlightBlock(const QString &text)
|
||||||
|
{
|
||||||
|
if (!text.isEmpty() && text.at(0) != ' ') {
|
||||||
|
QTextCharFormat format;
|
||||||
|
format.setForeground(QColor(128, 128, 128));
|
||||||
|
setFormat(0, text.size(), format);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class DisassemblerViewAgent
|
\class DisassemblerViewAgent
|
||||||
|
|
||||||
@@ -177,6 +202,7 @@ void DisassemblerViewAgent::setContents(const QString &contents)
|
|||||||
using namespace Core;
|
using namespace Core;
|
||||||
using namespace TextEditor;
|
using namespace TextEditor;
|
||||||
|
|
||||||
|
QPlainTextEdit *plainTextEdit = 0;
|
||||||
EditorManager *editorManager = EditorManager::instance();
|
EditorManager *editorManager = EditorManager::instance();
|
||||||
if (!d->editor) {
|
if (!d->editor) {
|
||||||
QString titlePattern = "Disassembler";
|
QString titlePattern = "Disassembler";
|
||||||
@@ -184,12 +210,13 @@ void DisassemblerViewAgent::setContents(const QString &contents)
|
|||||||
editorManager->openEditorWithContents(
|
editorManager->openEditorWithContents(
|
||||||
Core::Constants::K_DEFAULT_TEXT_EDITOR,
|
Core::Constants::K_DEFAULT_TEXT_EDITOR,
|
||||||
&titlePattern));
|
&titlePattern));
|
||||||
|
if ((plainTextEdit = qobject_cast<QPlainTextEdit *>(d->editor->widget())))
|
||||||
|
(void) new DisassemblerHighlighter(plainTextEdit);
|
||||||
}
|
}
|
||||||
|
|
||||||
editorManager->activateEditor(d->editor);
|
editorManager->activateEditor(d->editor);
|
||||||
|
|
||||||
QPlainTextEdit *plainTextEdit =
|
plainTextEdit = qobject_cast<QPlainTextEdit *>(d->editor->widget());
|
||||||
qobject_cast<QPlainTextEdit *>(d->editor->widget());
|
|
||||||
if (plainTextEdit)
|
if (plainTextEdit)
|
||||||
plainTextEdit->setPlainText(contents);
|
plainTextEdit->setPlainText(contents);
|
||||||
|
|
||||||
|
@@ -260,7 +260,7 @@ public:
|
|||||||
CombinedPane(QWidget *parent)
|
CombinedPane(QWidget *parent)
|
||||||
: DebuggerPane(parent)
|
: DebuggerPane(parent)
|
||||||
{
|
{
|
||||||
(void)new OutputHighlighter(this);
|
(void) new OutputHighlighter(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
@@ -1256,6 +1256,19 @@ void GdbEngine::handleAsyncOutput2(const GdbMi &data)
|
|||||||
{
|
{
|
||||||
qq->notifyInferiorStopped();
|
qq->notifyInferiorStopped();
|
||||||
|
|
||||||
|
// Sometimes we get some interesting extra information. Grab it.
|
||||||
|
GdbMi frame = data.findChild("frame");
|
||||||
|
GdbMi shortName = frame.findChild("file");
|
||||||
|
GdbMi fullName = frame.findChild("fullname");
|
||||||
|
if (shortName.isValid() && fullName.isValid()) {
|
||||||
|
QString file = QFile::decodeName(shortName.data());
|
||||||
|
QString full = QFile::decodeName(fullName.data());
|
||||||
|
if (file != full) {
|
||||||
|
m_shortToFullName[file] = full;
|
||||||
|
m_fullToShortName[full] = file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Stack
|
// Stack
|
||||||
//
|
//
|
||||||
@@ -1263,6 +1276,7 @@ void GdbEngine::handleAsyncOutput2(const GdbMi &data)
|
|||||||
updateLocals(); // Quick shot
|
updateLocals(); // Quick shot
|
||||||
|
|
||||||
int currentId = data.findChild("thread-id").data().toInt();
|
int currentId = data.findChild("thread-id").data().toInt();
|
||||||
|
|
||||||
reloadStack();
|
reloadStack();
|
||||||
if (supportsThreads())
|
if (supportsThreads())
|
||||||
postCommand(_("-thread-list-ids"), WatchUpdate, CB(handleStackListThreads), currentId);
|
postCommand(_("-thread-list-ids"), WatchUpdate, CB(handleStackListThreads), currentId);
|
||||||
@@ -1768,7 +1782,7 @@ void GdbEngine::stepExec()
|
|||||||
setTokenBarrier();
|
setTokenBarrier();
|
||||||
qq->notifyInferiorRunningRequested();
|
qq->notifyInferiorRunningRequested();
|
||||||
if (qq->isReverseDebugging())
|
if (qq->isReverseDebugging())
|
||||||
postCommand(_("reverse-step"), CB(handleExecContinue));
|
postCommand(_("-reverse-step"), CB(handleExecContinue));
|
||||||
else
|
else
|
||||||
postCommand(_("-exec-step"), CB(handleExecContinue));
|
postCommand(_("-exec-step"), CB(handleExecContinue));
|
||||||
}
|
}
|
||||||
@@ -1778,7 +1792,7 @@ void GdbEngine::stepIExec()
|
|||||||
setTokenBarrier();
|
setTokenBarrier();
|
||||||
qq->notifyInferiorRunningRequested();
|
qq->notifyInferiorRunningRequested();
|
||||||
if (qq->isReverseDebugging())
|
if (qq->isReverseDebugging())
|
||||||
postCommand(_("reverse-stepi"), CB(handleExecContinue));
|
postCommand(_("-reverse-stepi"), CB(handleExecContinue));
|
||||||
else
|
else
|
||||||
postCommand(_("-exec-step-instruction"), CB(handleExecContinue));
|
postCommand(_("-exec-step-instruction"), CB(handleExecContinue));
|
||||||
}
|
}
|
||||||
@@ -1795,7 +1809,7 @@ void GdbEngine::nextExec()
|
|||||||
setTokenBarrier();
|
setTokenBarrier();
|
||||||
qq->notifyInferiorRunningRequested();
|
qq->notifyInferiorRunningRequested();
|
||||||
if (qq->isReverseDebugging())
|
if (qq->isReverseDebugging())
|
||||||
postCommand(_("reverse-next"), CB(handleExecContinue));
|
postCommand(_("-reverse-next"), CB(handleExecContinue));
|
||||||
else
|
else
|
||||||
postCommand(_("-exec-next"), CB(handleExecContinue));
|
postCommand(_("-exec-next"), CB(handleExecContinue));
|
||||||
}
|
}
|
||||||
@@ -1805,9 +1819,9 @@ void GdbEngine::nextIExec()
|
|||||||
setTokenBarrier();
|
setTokenBarrier();
|
||||||
qq->notifyInferiorRunningRequested();
|
qq->notifyInferiorRunningRequested();
|
||||||
if (qq->isReverseDebugging())
|
if (qq->isReverseDebugging())
|
||||||
postCommand(_("reverse-nexti"), CB(handleExecContinue));
|
postCommand(_("-reverse-nexti"), CB(handleExecContinue));
|
||||||
else
|
else
|
||||||
postCommand(_("exec-next-instruction"), CB(handleExecContinue));
|
postCommand(_("-exec-next-instruction"), CB(handleExecContinue));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::runToLineExec(const QString &fileName, int lineNumber)
|
void GdbEngine::runToLineExec(const QString &fileName, int lineNumber)
|
||||||
@@ -1921,9 +1935,9 @@ void GdbEngine::breakpointDataFromOutput(BreakpointData *data, const GdbMi &bkpt
|
|||||||
else
|
else
|
||||||
data->bpAddress = _(child.data());
|
data->bpAddress = _(child.data());
|
||||||
} else if (child.hasName("file")) {
|
} else if (child.hasName("file")) {
|
||||||
files.append(QString::fromLocal8Bit(child.data()));
|
files.append(QFile::decodeName(child.data()));
|
||||||
} else if (child.hasName("fullname")) {
|
} else if (child.hasName("fullname")) {
|
||||||
QString fullName = QString::fromLocal8Bit(child.data());
|
QString fullName = QFile::decodeName(child.data());
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
fullName = QDir::cleanPath(fullName);
|
fullName = QDir::cleanPath(fullName);
|
||||||
#endif
|
#endif
|
||||||
@@ -2446,8 +2460,8 @@ void GdbEngine::handleStackListFrames(const GdbResultRecord &record, const QVari
|
|||||||
const GdbMi frameMi = stack.childAt(i);
|
const GdbMi frameMi = stack.childAt(i);
|
||||||
StackFrame frame(i);
|
StackFrame frame(i);
|
||||||
QStringList files;
|
QStringList files;
|
||||||
files.append(QString::fromLocal8Bit(frameMi.findChild("fullname").data()));
|
files.append(QFile::decodeName(frameMi.findChild("fullname").data()));
|
||||||
files.append(QString::fromLocal8Bit(frameMi.findChild("file").data()));
|
files.append(QFile::decodeName(frameMi.findChild("file").data()));
|
||||||
frame.file = fullName(files);
|
frame.file = fullName(files);
|
||||||
frame.function = _(frameMi.findChild("func").data());
|
frame.function = _(frameMi.findChild("func").data());
|
||||||
frame.from = _(frameMi.findChild("from").data());
|
frame.from = _(frameMi.findChild("from").data());
|
||||||
@@ -4035,7 +4049,7 @@ static QByteArray parseLine(const GdbMi &line)
|
|||||||
return ba;
|
return ba;
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString parseDisassembler(const GdbMi &lines)
|
QString GdbEngine::parseDisassembler(const GdbMi &lines)
|
||||||
{
|
{
|
||||||
// ^done,data={asm_insns=[src_and_asm_line={line="1243",file=".../app.cpp",
|
// ^done,data={asm_insns=[src_and_asm_line={line="1243",file=".../app.cpp",
|
||||||
// line_asm_insn=[{address="0x08054857",func-name="main",offset="27",
|
// line_asm_insn=[{address="0x08054857",func-name="main",offset="27",
|
||||||
@@ -4058,16 +4072,15 @@ static QString parseDisassembler(const GdbMi &lines)
|
|||||||
if (child.hasName("src_and_asm_line")) {
|
if (child.hasName("src_and_asm_line")) {
|
||||||
// mixed mode
|
// mixed mode
|
||||||
int line = child.findChild("line").data().toInt();
|
int line = child.findChild("line").data().toInt();
|
||||||
QByteArray fileName = child.findChild("file").data();
|
QString fileName = QFile::decodeName(child.findChild("file").data());
|
||||||
if (!fileLoaded) {
|
if (!fileLoaded) {
|
||||||
QFile file(QFile::decodeName(fileName));
|
QFile file(fullName(fileName));
|
||||||
file.open(QIODevice::ReadOnly);
|
file.open(QIODevice::ReadOnly);
|
||||||
fileContents = file.readAll().split('\n');
|
fileContents = file.readAll().split('\n');
|
||||||
fileLoaded = true;
|
fileLoaded = true;
|
||||||
}
|
}
|
||||||
if (line >= 0 && line < fileContents.size())
|
if (line >= 0 && line < fileContents.size())
|
||||||
ba += " " + fileContents.at(line) + '\n';
|
ba += " " + fileContents.at(line) + '\n';
|
||||||
|
|
||||||
GdbMi insn = child.findChild("line_asm_insn");
|
GdbMi insn = child.findChild("line_asm_insn");
|
||||||
foreach (const GdbMi &line, insn.children())
|
foreach (const GdbMi &line, insn.children())
|
||||||
ba += parseLine(line);
|
ba += parseLine(line);
|
||||||
|
@@ -144,7 +144,6 @@ private:
|
|||||||
//
|
//
|
||||||
|
|
||||||
int currentFrame() const;
|
int currentFrame() const;
|
||||||
//QString currentWorkingDirectory() const { return m_pwd; }
|
|
||||||
|
|
||||||
bool supportsThreads() const;
|
bool supportsThreads() const;
|
||||||
|
|
||||||
@@ -162,12 +161,12 @@ public: // otherwise the Qt flag macros are unhappy
|
|||||||
NeedsStop = 1,
|
NeedsStop = 1,
|
||||||
Discardable = 2,
|
Discardable = 2,
|
||||||
RebuildModel = 4,
|
RebuildModel = 4,
|
||||||
WatchUpdate = Discardable|RebuildModel,
|
WatchUpdate = Discardable | RebuildModel,
|
||||||
EmbedToken = 8
|
EmbedToken = 8
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(GdbCommandFlags, GdbCommandFlag)
|
Q_DECLARE_FLAGS(GdbCommandFlags, GdbCommandFlag)
|
||||||
private:
|
|
||||||
|
|
||||||
|
private:
|
||||||
typedef void (GdbEngine::*GdbCommandCallback)(const GdbResultRecord &record, const QVariant &cookie);
|
typedef void (GdbEngine::*GdbCommandCallback)(const GdbResultRecord &record, const QVariant &cookie);
|
||||||
|
|
||||||
struct GdbCommand
|
struct GdbCommand
|
||||||
@@ -372,6 +371,7 @@ private:
|
|||||||
void setLocals(const QList<GdbMi> &locals);
|
void setLocals(const QList<GdbMi> &locals);
|
||||||
|
|
||||||
bool startModeAllowsDumpers() const;
|
bool startModeAllowsDumpers() const;
|
||||||
|
QString parseDisassembler(const GdbMi &lines);
|
||||||
|
|
||||||
int m_pendingRequests;
|
int m_pendingRequests;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user