Commit 90657a49 authored by hjk's avatar hjk

debugger: small usability fixes for dissassembler, breakpoint view, location

parent 714f7656
......@@ -34,6 +34,7 @@
#include "debuggercore.h"
#include "debuggerengine.h"
#include "debuggerstringutils.h"
#include "stackframe.h"
#include <utils/qtcassert.h>
......@@ -140,7 +141,7 @@ BreakpointId BreakHandler::findSimilarBreakpoint(const BreakpointResponse &needl
const BreakpointId id = it.key();
const BreakpointParameters &data = it->data;
const BreakpointResponse &response = it->response;
qDebug() << "COMPARING " << data.toString() << " WITH " << needle.toString();
//qDebug() << "COMPARING " << data.toString() << " WITH " << needle.toString();
if (response.number && response.number == needle.number)
return id;
......@@ -353,10 +354,10 @@ BreakpointId BreakHandler::findBreakpointByIndex(const QModelIndex &index) const
BreakpointIds BreakHandler::findBreakpointsByIndex(const QList<QModelIndex> &list) const
{
BreakpointIds ids;
QSet<BreakpointId> ids;
foreach (const QModelIndex &index, list)
ids.append(findBreakpointByIndex(index));
return ids;
ids.insert(findBreakpointByIndex(index));
return ids.toList();
}
Qt::ItemFlags BreakHandler::flags(const QModelIndex &index) const
......@@ -467,7 +468,7 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
if (role == Qt::DisplayRole) {
QString displayValue;
const quint64 address =
data.isWatchpoint() ? data.address : response.address;
it->isPending() ? data.address : response.address;
if (address)
displayValue += QString::fromAscii("0x%1").arg(address, 0, 16);
if (!response.extra.isEmpty()) {
......@@ -842,8 +843,17 @@ void BreakHandler::gotoLocation(BreakpointId id) const
{
ConstIterator it = m_storage.find(id);
QTC_ASSERT(it != m_storage.end(), return);
debuggerCore()->gotoLocation(
it->data.fileName, it->data.lineNumber, false);
if (it->data.type == BreakpointByAddress) {
StackFrame frame;
frame.address = it->data.address;
DebuggerEngine *engine = debuggerCore()->currentEngine();
if (engine)
engine->gotoLocation(frame, false);
} else {
const QString fileName = it->markerFileName();
const int lineNumber = it->markerLineNumber();
debuggerCore()->gotoLocation(fileName, lineNumber, false);
}
}
void BreakHandler::updateLineNumberFromMarker(BreakpointId id, int lineNumber)
......
......@@ -74,13 +74,13 @@ QString BreakpointParameters::toString() const
{
QString result;
QTextStream ts(&result);
ts << fileName;
ts << condition;
ts << ignoreCount;
ts << lineNumber;
ts << address;
ts << functionName;
ts << useFullPath;
ts << " FileName: " << fileName;
ts << " Condition: " << condition;
ts << " IgnoreCount: " << ignoreCount;
ts << " LineNumber: " << lineNumber;
ts << " Address: " << address;
ts << " FunctionName: " << functionName;
ts << " UseFullPath: " << useFullPath;
return result;
}
......@@ -99,12 +99,12 @@ QString BreakpointResponse::toString() const
{
QString result;
QTextStream ts(&result);
ts << number;
ts << pending;
ts << fullName;
ts << multiple;
ts << extra;
ts << correctedLineNumber;
ts << " Number: " << number;
ts << " Pending: " << pending;
ts << " FullName: " << fullName;
ts << " Multiple: " << multiple;
ts << " Extra: " << extra;
ts << " CorrectedLineNumber: " << correctedLineNumber;
return result + BreakpointParameters::toString();
}
......
This diff is collapsed.
......@@ -61,12 +61,11 @@ private:
void keyPressEvent(QKeyEvent *ev);
void mouseDoubleClickEvent(QMouseEvent *ev);
void deleteBreakpoints(const QModelIndexList &list);
void deleteBreakpoints(const BreakpointIds &ids);
void addBreakpoint();
void editBreakpoints(const QModelIndexList &list);
void associateBreakpoint(const QModelIndexList &list, int thread);
void setBreakpointsEnabled(const QModelIndexList &list, bool enabled);
void setBreakpointsFullPath(const QModelIndexList &list, bool fullpath);
void editBreakpoints(const BreakpointIds &ids);
void associateBreakpoint(const BreakpointIds &ids, int thread);
void setBreakpointsEnabled(const BreakpointIds &ids, bool enabled);
bool m_alwaysResizeColumnsToContents;
};
......
......@@ -210,6 +210,7 @@ struct DisassemblerViewAgentPrivate
QPointer<TextEditor::ITextEditor> editor;
StackFrame frame;
bool tryMixed;
bool setMarker;
QPointer<DebuggerEngine> engine;
LocationMark2 *locationMark;
QHash<QString, QString> cache;
......@@ -219,6 +220,7 @@ struct DisassemblerViewAgentPrivate
DisassemblerViewAgentPrivate::DisassemblerViewAgentPrivate() :
editor(0),
tryMixed(true),
setMarker(true),
locationMark(new LocationMark2),
mimeType(_("text/x-qtcreator-generic-asm"))
{
......@@ -279,9 +281,11 @@ bool DisassemblerViewAgent::isMixed() const
&& d->frame.function != _("??");
}
void DisassemblerViewAgent::setFrame(const StackFrame &frame, bool tryMixed)
void DisassemblerViewAgent::setFrame(const StackFrame &frame, bool tryMixed,
bool setMarker)
{
d->frame = frame;
d->setMarker = setMarker;
d->tryMixed = tryMixed;
if (isMixed()) {
QHash<QString, QString>::ConstIterator it = d->cache.find(frameKey(frame));
......@@ -342,7 +346,7 @@ static QPair<int, int> lineNumberOfAddress(const QString &disassembly, quint64 a
const int size = disassembly.size();
for (int lineNumber = 1; pos < size; lineNumber++) {
int endOfLinePos = disassembly.indexOf(newLine, pos + 1);
int endOfLinePos = disassembly.indexOf(newLine, pos);
if (endOfLinePos == -1)
endOfLinePos = size;
const QString line = disassembly.mid(pos, endOfLinePos - pos);
......@@ -382,12 +386,15 @@ void DisassemblerViewAgent::setContents(const QString &contents)
plainTextEdit->setReadOnly(true);
}
d->editor->markableInterface()->removeMark(d->locationMark);
if (d->setMarker)
d->editor->markableInterface()->removeMark(d->locationMark);
d->editor->setDisplayName(_("Disassembler (%1)").arg(d->frame.function));
const QPair<int, int> lineNumberPos = lineNumberOfAddress(contents, d->frame.address);
const QPair<int, int> lineNumberPos =
lineNumberOfAddress(contents, d->frame.address);
if (lineNumberPos.first > 0) {
d->editor->markableInterface()->addMark(d->locationMark, lineNumberPos.first);
if (d->setMarker)
d->editor->markableInterface()->addMark(d->locationMark, lineNumberPos.first);
if (plainTextEdit) {
QTextCursor tc = plainTextEdit->textCursor();
tc.setPosition(lineNumberPos.second);
......@@ -399,7 +406,6 @@ void DisassemblerViewAgent::setContents(const QString &contents)
bool DisassemblerViewAgent::contentsCoversAddress(const QString &contents) const
{
QTC_ASSERT(d, return false);
return lineNumberOfAddress(contents, d->frame.address).first > 0;
}
......
......@@ -83,7 +83,7 @@ public:
explicit DisassemblerViewAgent(Debugger::DebuggerEngine *engine);
~DisassemblerViewAgent();
void setFrame(const StackFrame &frame, bool tryMixed = true);
void setFrame(const StackFrame &frame, bool tryMixed, bool setMarker);
const StackFrame &frame() const;
void resetLocation();
Q_SLOT void setContents(const QString &contents);
......
......@@ -516,21 +516,15 @@ void DebuggerEngine::resetLocation()
void DebuggerEngine::gotoLocation(const QString &fileName, int lineNumber, bool setMarker)
{
StackFrame frame;
frame.file = fileName;
frame.line = lineNumber;
gotoLocation(frame, setMarker);
debuggerCore()->gotoLocation(fileName, lineNumber, setMarker);
}
void DebuggerEngine::gotoLocation(const StackFrame &frame, bool setMarker)
{
if (debuggerCore()->boolSetting(OperateByInstruction) || !frame.isUsable()) {
if (setMarker)
resetLocation();
d->m_disassemblerViewAgent.setFrame(frame);
} else {
if (debuggerCore()->boolSetting(OperateByInstruction) || !frame.isUsable())
d->m_disassemblerViewAgent.setFrame(frame, true, setMarker);
else
debuggerCore()->gotoLocation(frame.file, frame.line, setMarker);
}
}
// Called from RunControl.
......
......@@ -395,46 +395,13 @@ const char * const SNAPSHOT_KEY = "Ctrl+D,Ctrl+S";
#endif
} // namespace Constants
} // namespace Debugger
static SessionManager *sessionManager()
{
return ProjectExplorerPlugin::instance()->session();
}
static QToolButton *toolButton(QAction *action)
{
QToolButton *button = new QToolButton;
button->setDefaultAction(action);
return button;
}
// Retrieve file name and line and optionally address
// from the data set on the text editor context menu action.
static bool positionFromContextActionData(const QObject *sender,
QString *fileName,
int *lineNumber,
quint64 *address = 0)
{
if (const QAction *action = qobject_cast<const QAction *>(sender)) {
const QVariantList data = action->data().toList();
if (data.size() >= (address ? 3 : 2)) {
*fileName = data.front().toString();
*lineNumber = data.at(1).toInt();
if (address)
*address = data.at(2).toULongLong();
return true;
}
}
return false;
}
namespace Debugger {
namespace Cdb {
void addCdb2OptionPages(QList<Core::IOptionsPage*> *);
} // namespace Cdb
namespace Internal {
// FIXME: Outdated?
......@@ -450,6 +417,34 @@ void addTcfOptionPages(QList<IOptionsPage*> *opts);
void addCdbOptionPages(QList<IOptionsPage*> *opts);
#endif
static SessionManager *sessionManager()
{
return ProjectExplorerPlugin::instance()->session();
}
static QToolButton *toolButton(QAction *action)
{
QToolButton *button = new QToolButton;
button->setDefaultAction(action);
return button;
}
// Retrieve file name and line and optionally address
// from the data set on the text editor context menu action.
static bool positionFromContextActionData(const QObject *sender,
QString *fileName, int *lineNumber, quint64 *address = 0)
{
const QAction *action = qobject_cast<const QAction *>(sender);
QTC_ASSERT(action, return false);
const QVariantList data = action->data().toList();
QTC_ASSERT(data.size() == 3, return false);
*fileName = data.front().toString();
*lineNumber = data.at(1).toInt();
if (address)
*address = data.at(2).toULongLong();
return true;
}
struct AttachRemoteParameters
{
AttachRemoteParameters() : attachPid(0), winCrashEvent(0) {}
......@@ -917,7 +912,7 @@ public slots:
quint64 address;
if (positionFromContextActionData(sender(), &fileName, &lineNumber, &address))
m_breakHandler->toggleBreakpoint(fileName, lineNumber, address);
}
}
void breakpointRemoveMarginActionTriggered()
{
......@@ -2391,7 +2386,9 @@ void DebuggerPluginPrivate::requestContextMenu(TextEditor::ITextEditor *editor,
QString line = editor->contents()
.section('\n', lineNumber - 1, lineNumber - 1);
BreakpointResponse needle;
needle.type = BreakpointByAddress;
needle.address = DisassemblerViewAgent::addressFromDisassemblyLine(line);
address = needle.address;
needle.lineNumber = -1;
id = breakHandler()->findSimilarBreakpoint(needle);
} else {
......
......@@ -1186,8 +1186,9 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
}
// Quickly set the location marker.
if (lineNumber && QFileInfo(fullName).exists())
debuggerCore()->gotoLocation(fullName, lineNumber, true);
if (lineNumber && !debuggerCore()->boolSetting(OperateByInstruction)
&& QFileInfo(fullName).exists())
gotoLocation(fullName, lineNumber, true);
if (!m_commandsToRunOnTemporaryBreak.isEmpty()) {
QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state())
......@@ -1443,7 +1444,7 @@ void GdbEngine::handleStop1(const GdbMi &data)
//
// Stack
//
reloadStack(false);
reloadStack(false); // Will trigger register reload.
if (supportsThreads()) {
int currentId = data.findChild("thread-id").data().toInt();
......@@ -1458,11 +1459,6 @@ void GdbEngine::handleStop1(const GdbMi &data)
CB(handleThreadInfo), currentId);
}
}
//
// Registers
//
reloadRegisters();
}
void GdbEngine::handleInfoProc(const GdbResponse &response)
......@@ -2886,8 +2882,7 @@ void GdbEngine::handleStackSelectThread(const GdbResponse &)
{
QTC_ASSERT(state() == InferiorUnrunnable || state() == InferiorStopOk, /**/);
showStatusMessage(tr("Retrieving data for stack view..."), 3000);
reloadRegisters();
reloadStack(true);
reloadStack(true); // Will reload registers.
updateLocals();
}
......@@ -2943,6 +2938,7 @@ void GdbEngine::handleStackListFrames(const GdbResponse &response)
// ^error,data={msg="Previous frame identical to this frame (corrupt stack?)"
// logstreamoutput="Previous frame identical to this frame (corrupt stack?)\n"
//qDebug() << "LISTING STACK FAILED: " << response.toString();
reloadRegisters();
return;
}
......@@ -4039,17 +4035,35 @@ void GdbEngine::handleFetchDisassemblerByCli(const GdbResponse &response)
// "Dump of assembler code from 0xb7ff598f to 0xb7ff5a07:"
GdbMi output = response.data.findChild("consolestreamoutput");
QByteArray res;
QByteArray lastFunction;
foreach (const QByteArray &line0, output.data().split('\n')) {
QByteArray line = line0.trimmed();
if (line.startsWith("=> "))
line = line.mid(3);
if (line.isEmpty())
continue;
if (line.startsWith("Current language:"))
continue;
if (line.startsWith("Dump of assembler"))
continue;
if (line.startsWith("The current source"))
continue;
if (line.startsWith("End of assembler"))
continue;
if (line.startsWith("0x")) {
int pos1 = line.indexOf('<') + 1;
int pos2 = line.indexOf('+', pos1);
int pos3 = line.indexOf('>', pos1);
if (pos1 < pos2 && pos2 < pos3) {
QByteArray function = line.mid(pos1, pos2 - pos1);
if (function != lastFunction) {
res.append("\nFunction: ");
res.append(function);
res.append('\n');
lastFunction = function;
}
line.replace(pos1, pos2 - pos1, "");
}
res.append(line);
res.append('\n');
continue;
......
......@@ -162,7 +162,7 @@ void StackWindow::contextMenuEvent(QContextMenuEvent *ev)
(void) new MemoryViewAgent(currentEngine(), address);
else if (act == actShowDisassembler) {
DisassemblerViewAgent *agent = new DisassemblerViewAgent(engine);
agent->setFrame(frame);
agent->setFrame(frame, true, false);
}
}
......
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