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

This commit is contained in:
hjk
2010-11-24 11:44:43 +01:00
parent 714f7656a6
commit 90657a496b
10 changed files with 154 additions and 152 deletions

View File

@@ -34,6 +34,7 @@
#include "debuggercore.h" #include "debuggercore.h"
#include "debuggerengine.h" #include "debuggerengine.h"
#include "debuggerstringutils.h" #include "debuggerstringutils.h"
#include "stackframe.h"
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
@@ -140,7 +141,7 @@ BreakpointId BreakHandler::findSimilarBreakpoint(const BreakpointResponse &needl
const BreakpointId id = it.key(); const BreakpointId id = it.key();
const BreakpointParameters &data = it->data; const BreakpointParameters &data = it->data;
const BreakpointResponse &response = it->response; 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) if (response.number && response.number == needle.number)
return id; return id;
@@ -353,10 +354,10 @@ BreakpointId BreakHandler::findBreakpointByIndex(const QModelIndex &index) const
BreakpointIds BreakHandler::findBreakpointsByIndex(const QList<QModelIndex> &list) const BreakpointIds BreakHandler::findBreakpointsByIndex(const QList<QModelIndex> &list) const
{ {
BreakpointIds ids; QSet<BreakpointId> ids;
foreach (const QModelIndex &index, list) foreach (const QModelIndex &index, list)
ids.append(findBreakpointByIndex(index)); ids.insert(findBreakpointByIndex(index));
return ids; return ids.toList();
} }
Qt::ItemFlags BreakHandler::flags(const QModelIndex &index) const 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) { if (role == Qt::DisplayRole) {
QString displayValue; QString displayValue;
const quint64 address = const quint64 address =
data.isWatchpoint() ? data.address : response.address; it->isPending() ? data.address : response.address;
if (address) if (address)
displayValue += QString::fromAscii("0x%1").arg(address, 0, 16); displayValue += QString::fromAscii("0x%1").arg(address, 0, 16);
if (!response.extra.isEmpty()) { if (!response.extra.isEmpty()) {
@@ -842,8 +843,17 @@ void BreakHandler::gotoLocation(BreakpointId id) const
{ {
ConstIterator it = m_storage.find(id); ConstIterator it = m_storage.find(id);
QTC_ASSERT(it != m_storage.end(), return); QTC_ASSERT(it != m_storage.end(), return);
debuggerCore()->gotoLocation( if (it->data.type == BreakpointByAddress) {
it->data.fileName, it->data.lineNumber, false); 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) void BreakHandler::updateLineNumberFromMarker(BreakpointId id, int lineNumber)

View File

@@ -74,13 +74,13 @@ QString BreakpointParameters::toString() const
{ {
QString result; QString result;
QTextStream ts(&result); QTextStream ts(&result);
ts << fileName; ts << " FileName: " << fileName;
ts << condition; ts << " Condition: " << condition;
ts << ignoreCount; ts << " IgnoreCount: " << ignoreCount;
ts << lineNumber; ts << " LineNumber: " << lineNumber;
ts << address; ts << " Address: " << address;
ts << functionName; ts << " FunctionName: " << functionName;
ts << useFullPath; ts << " UseFullPath: " << useFullPath;
return result; return result;
} }
@@ -99,12 +99,12 @@ QString BreakpointResponse::toString() const
{ {
QString result; QString result;
QTextStream ts(&result); QTextStream ts(&result);
ts << number; ts << " Number: " << number;
ts << pending; ts << " Pending: " << pending;
ts << fullName; ts << " FullName: " << fullName;
ts << multiple; ts << " Multiple: " << multiple;
ts << extra; ts << " Extra: " << extra;
ts << correctedLineNumber; ts << " CorrectedLineNumber: " << correctedLineNumber;
return result + BreakpointParameters::toString(); return result + BreakpointParameters::toString();
} }

View File

@@ -335,15 +335,6 @@ void BreakWindow::showAddressColumn(bool on)
setColumnHidden(7, !on); setColumnHidden(7, !on);
} }
static QModelIndexList normalizeIndexes(const QModelIndexList &list)
{
QModelIndexList res;
foreach (const QModelIndex &index, list)
if (index.column() == 0)
res.append(index);
return res;
}
void BreakWindow::keyPressEvent(QKeyEvent *ev) void BreakWindow::keyPressEvent(QKeyEvent *ev)
{ {
if (ev->key() == Qt::Key_Delete) { if (ev->key() == Qt::Key_Delete) {
@@ -351,8 +342,11 @@ void BreakWindow::keyPressEvent(QKeyEvent *ev)
QTC_ASSERT(sm, return); QTC_ASSERT(sm, return);
QModelIndexList si = sm->selectedIndexes(); QModelIndexList si = sm->selectedIndexes();
if (si.isEmpty()) if (si.isEmpty())
si.append(currentIndex().sibling(currentIndex().row(), 0)); si.append(currentIndex());
deleteBreakpoints(normalizeIndexes(si)); const BreakpointIds ids = breakHandler()->findBreakpointsByIndex(si);
int row = qMin(model()->rowCount() - ids.size() - 1, currentIndex().row());
deleteBreakpoints(ids);
setCurrentIndex(si.at(0).sibling(row, 0));
} }
QTreeView::keyPressEvent(ev); QTreeView::keyPressEvent(ev);
} }
@@ -365,8 +359,10 @@ void BreakWindow::resizeEvent(QResizeEvent *ev)
void BreakWindow::mouseDoubleClickEvent(QMouseEvent *ev) void BreakWindow::mouseDoubleClickEvent(QMouseEvent *ev)
{ {
QModelIndex indexUnderMouse = indexAt(ev->pos()); QModelIndex indexUnderMouse = indexAt(ev->pos());
if (indexUnderMouse.isValid() && indexUnderMouse.column() >= 4) if (indexUnderMouse.isValid() && indexUnderMouse.column() >= 4) {
editBreakpoints(QModelIndexList() << indexUnderMouse); BreakpointId id = breakHandler()->findBreakpointByIndex(indexUnderMouse);
editBreakpoints(BreakpointIds() << id);
}
QTreeView::mouseDoubleClickEvent(ev); QTreeView::mouseDoubleClickEvent(ev);
} }
@@ -375,34 +371,35 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
QMenu menu; QMenu menu;
QItemSelectionModel *sm = selectionModel(); QItemSelectionModel *sm = selectionModel();
QTC_ASSERT(sm, return); QTC_ASSERT(sm, return);
QModelIndexList si = sm->selectedIndexes(); QModelIndexList selectedIndices = sm->selectedIndexes();
QModelIndex indexUnderMouse = indexAt(ev->pos()); QModelIndex indexUnderMouse = indexAt(ev->pos());
if (si.isEmpty() && indexUnderMouse.isValid()) if (selectedIndices.isEmpty() && indexUnderMouse.isValid())
si.append(indexUnderMouse.sibling(indexUnderMouse.row(), 0)); selectedIndices.append(indexUnderMouse);
si = normalizeIndexes(si);
BreakHandler *handler = breakHandler();
BreakpointIds selectedIds = handler->findBreakpointsByIndex(selectedIndices);
const int rowCount = model()->rowCount(); const int rowCount = model()->rowCount();
const unsigned engineCapabilities = BreakOnThrowAndCatchCapability; const unsigned engineCapabilities = BreakOnThrowAndCatchCapability;
BreakHandler *handler = breakHandler();
// FIXME BP: model()->data(QModelIndex(), EngineCapabilitiesRole).toUInt(); // FIXME BP: model()->data(QModelIndex(), EngineCapabilitiesRole).toUInt();
QAction *deleteAction = new QAction(tr("Delete Breakpoint"), &menu); QAction *deleteAction = new QAction(tr("Delete Breakpoint"), &menu);
deleteAction->setEnabled(si.size() > 0); deleteAction->setEnabled(!selectedIds.isEmpty());
QAction *deleteAllAction = new QAction(tr("Delete All Breakpoints"), &menu); QAction *deleteAllAction = new QAction(tr("Delete All Breakpoints"), &menu);
deleteAllAction->setEnabled(model()->rowCount() > 0); deleteAllAction->setEnabled(model()->rowCount() > 0);
// Delete by file: Find indices of breakpoints of the same file. // Delete by file: Find indices of breakpoints of the same file.
QAction *deleteByFileAction = 0; QAction *deleteByFileAction = 0;
QList<QModelIndex> breakPointsOfFile; BreakpointIds breakpointsInFile;
if (indexUnderMouse.isValid()) { if (indexUnderMouse.isValid()) {
const QModelIndex index = indexUnderMouse.sibling(indexUnderMouse.row(), 2); const QModelIndex index = indexUnderMouse.sibling(indexUnderMouse.row(), 2);
const QString file = model()->data(index).toString(); const QString file = index.data().toString();
if (!file.isEmpty()) { if (!file.isEmpty()) {
for (int i = 0; i < rowCount; i++) for (int i = 0; i < rowCount; i++)
if (model()->data(model()->index(i, 2)).toString() == file) if (index.data().toString() == file)
breakPointsOfFile.push_back(model()->index(i, 2)); breakpointsInFile.append(handler->findBreakpointByIndex(index));
if (breakPointsOfFile.size() > 1) { if (breakpointsInFile.size() > 1) {
deleteByFileAction = deleteByFileAction =
new QAction(tr("Delete Breakpoints of \"%1\"").arg(file), &menu); new QAction(tr("Delete Breakpoints of \"%1\"").arg(file), &menu);
deleteByFileAction->setEnabled(true); deleteByFileAction->setEnabled(true);
@@ -425,7 +422,7 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
QAction *editBreakpointAction = QAction *editBreakpointAction =
new QAction(tr("Edit Breakpoint..."), &menu); new QAction(tr("Edit Breakpoint..."), &menu);
editBreakpointAction->setEnabled(si.size() > 0); editBreakpointAction->setEnabled(!selectedIds.isEmpty());
int threadId = 0; int threadId = 0;
// FIXME BP: m_engine->threadsHandler()->currentThreadId(); // FIXME BP: m_engine->threadsHandler()->currentThreadId();
@@ -433,18 +430,15 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
? tr("Associate Breakpoint With All Threads") ? tr("Associate Breakpoint With All Threads")
: tr("Associate Breakpoint With Thread %1").arg(threadId); : tr("Associate Breakpoint With Thread %1").arg(threadId);
QAction *associateBreakpointAction = new QAction(associateTitle, &menu); QAction *associateBreakpointAction = new QAction(associateTitle, &menu);
associateBreakpointAction->setEnabled(si.size() > 0); associateBreakpointAction->setEnabled(!selectedIds.isEmpty());
QAction *synchronizeAction = QAction *synchronizeAction =
new QAction(tr("Synchronize Breakpoints"), &menu); new QAction(tr("Synchronize Breakpoints"), &menu);
synchronizeAction->setEnabled(debuggerCore()->hasSnapshots()); synchronizeAction->setEnabled(debuggerCore()->hasSnapshots());
QModelIndex idx0 = (si.size() ? si.front() : QModelIndex()); bool enabled = selectedIds.isEmpty() || handler->isEnabled(selectedIds.at(0));
const BreakpointId id = handler->findBreakpointByIndex(idx0);
bool enabled = si.isEmpty() || handler->isEnabled(id); const QString str5 = selectedIds.size() > 1
const QString str5 = si.size() > 1
? enabled ? enabled
? tr("Disable Selected Breakpoints") ? tr("Disable Selected Breakpoints")
: tr("Enable Selected Breakpoints") : tr("Enable Selected Breakpoints")
@@ -452,7 +446,7 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
? tr("Disable Breakpoint") ? tr("Disable Breakpoint")
: tr("Enable Breakpoint"); : tr("Enable Breakpoint");
QAction *toggleEnabledAction = new QAction(str5, &menu); QAction *toggleEnabledAction = new QAction(str5, &menu);
toggleEnabledAction->setEnabled(si.size() > 0); toggleEnabledAction->setEnabled(!selectedIds.isEmpty());
QAction *addBreakpointAction = QAction *addBreakpointAction =
new QAction(tr("Add Breakpoint..."), this); new QAction(tr("Add Breakpoint..."), this);
@@ -486,27 +480,24 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
QAction *act = menu.exec(ev->globalPos()); QAction *act = menu.exec(ev->globalPos());
if (act == deleteAction) { if (act == deleteAction)
deleteBreakpoints(si); deleteBreakpoints(selectedIds);
} else if (act == deleteAllAction) { else if (act == deleteAllAction)
QList<QModelIndex> allRows; deleteBreakpoints(handler->allBreakpointIds());
for (int i = 0; i < rowCount; i++) else if (act == deleteByFileAction)
allRows.push_back(model()->index(i, 0)); deleteBreakpoints(breakpointsInFile);
deleteBreakpoints(allRows);
} else if (act == deleteByFileAction)
deleteBreakpoints(breakPointsOfFile);
else if (act == adjustColumnAction) else if (act == adjustColumnAction)
resizeColumnsToContents(); resizeColumnsToContents();
else if (act == alwaysAdjustAction) else if (act == alwaysAdjustAction)
setAlwaysResizeColumnsToContents(!m_alwaysResizeColumnsToContents); setAlwaysResizeColumnsToContents(!m_alwaysResizeColumnsToContents);
else if (act == editBreakpointAction) else if (act == editBreakpointAction)
editBreakpoints(si); editBreakpoints(selectedIds);
else if (act == associateBreakpointAction) else if (act == associateBreakpointAction)
associateBreakpoint(si, threadId); associateBreakpoint(selectedIds, threadId);
else if (act == synchronizeAction) else if (act == synchronizeAction)
; //synchronizeBreakpoints(); ; //synchronizeBreakpoints();
else if (act == toggleEnabledAction) else if (act == toggleEnabledAction)
setBreakpointsEnabled(si, !enabled); setBreakpointsEnabled(selectedIds, !enabled);
else if (act == addBreakpointAction) else if (act == addBreakpointAction)
addBreakpoint(); addBreakpoint();
else if (act == breakAtThrowAction) else if (act == breakAtThrowAction)
@@ -515,24 +506,17 @@ void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
handler->appendBreakpoint(BreakpointParameters(BreakpointAtCatch)); handler->appendBreakpoint(BreakpointParameters(BreakpointAtCatch));
} }
void BreakWindow::setBreakpointsEnabled(const QModelIndexList &list, bool enabled) void BreakWindow::setBreakpointsEnabled(const BreakpointIds &ids, bool enabled)
{ {
BreakHandler *handler = breakHandler(); BreakHandler *handler = breakHandler();
foreach (const BreakpointId id, handler->findBreakpointsByIndex(list)) foreach (const BreakpointId id, ids)
handler->setEnabled(id, enabled); handler->setEnabled(id, enabled);
} }
void BreakWindow::setBreakpointsFullPath(const QModelIndexList &list, bool fullpath) void BreakWindow::deleteBreakpoints(const BreakpointIds &ids)
{ {
BreakHandler *handler = breakHandler(); BreakHandler *handler = breakHandler();
foreach (const BreakpointId id, handler->findBreakpointsByIndex(list)) foreach (const BreakpointId id, ids)
handler->setUseFullPath(id, fullpath);
}
void BreakWindow::deleteBreakpoints(const QModelIndexList &list)
{
BreakHandler *handler = breakHandler();
foreach (const BreakpointId id, handler->findBreakpointsByIndex(list))
handler->removeBreakpoint(id); handler->removeBreakpoint(id);
} }
@@ -552,15 +536,13 @@ void BreakWindow::addBreakpoint()
breakHandler()->appendBreakpoint(data); breakHandler()->appendBreakpoint(data);
} }
void BreakWindow::editBreakpoints(const QModelIndexList &list) void BreakWindow::editBreakpoints(const BreakpointIds &ids)
{ {
QTC_ASSERT(!list.isEmpty(), return); QTC_ASSERT(!ids.isEmpty(), return);
BreakHandler *handler = breakHandler();
const BreakpointIds ids = handler->findBreakpointsByIndex(list);
const BreakpointId id = ids.at(0); const BreakpointId id = ids.at(0);
if (list.size() == 1) { if (ids.size() == 1) {
editBreakpoint(id, this); editBreakpoint(id, this);
return; return;
} }
@@ -573,6 +555,7 @@ void BreakWindow::editBreakpoints(const QModelIndexList &list)
ui.lineEditIgnoreCount->setValidator( ui.lineEditIgnoreCount->setValidator(
new QIntValidator(0, 2147483647, ui.lineEditIgnoreCount)); new QIntValidator(0, 2147483647, ui.lineEditIgnoreCount));
BreakHandler *handler = breakHandler();
const QString oldCondition = QString::fromLatin1(handler->condition(id)); const QString oldCondition = QString::fromLatin1(handler->condition(id));
const QString oldIgnoreCount = QString::number(handler->ignoreCount(id)); const QString oldIgnoreCount = QString::number(handler->ignoreCount(id));
const QString oldThreadSpec = QString::fromLatin1(handler->threadSpec(id)); const QString oldThreadSpec = QString::fromLatin1(handler->threadSpec(id));
@@ -588,23 +571,22 @@ void BreakWindow::editBreakpoints(const QModelIndexList &list)
const QString newIgnoreCount = ui.lineEditIgnoreCount->text(); const QString newIgnoreCount = ui.lineEditIgnoreCount->text();
const QString newThreadSpec = ui.lineEditThreadSpec->text(); const QString newThreadSpec = ui.lineEditThreadSpec->text();
// Unchanged -> cancel
if (newCondition == oldCondition && newIgnoreCount == oldIgnoreCount if (newCondition == oldCondition && newIgnoreCount == oldIgnoreCount
&& newThreadSpec == oldThreadSpec) && newThreadSpec == oldThreadSpec)
return; return;
foreach (const BreakpointId id, handler->findBreakpointsByIndex(list)) { foreach (const BreakpointId id, ids) {
handler->setCondition(id, newCondition.toLatin1()); handler->setCondition(id, newCondition.toLatin1());
handler->setIgnoreCount(id, newIgnoreCount.toInt()); handler->setIgnoreCount(id, newIgnoreCount.toInt());
handler->setThreadSpec(id, newThreadSpec.toLatin1()); handler->setThreadSpec(id, newThreadSpec.toLatin1());
} }
} }
void BreakWindow::associateBreakpoint(const QModelIndexList &list, int threadId) void BreakWindow::associateBreakpoint(const BreakpointIds &ids, int threadId)
{ {
BreakHandler *handler = breakHandler(); BreakHandler *handler = breakHandler();
QByteArray spec = QByteArray::number(threadId); QByteArray spec = QByteArray::number(threadId);
foreach (const BreakpointId id, handler->findBreakpointsByIndex(list)) foreach (const BreakpointId id, ids)
handler->setThreadSpec(id, spec); handler->setThreadSpec(id, spec);
} }

View File

@@ -61,12 +61,11 @@ private:
void keyPressEvent(QKeyEvent *ev); void keyPressEvent(QKeyEvent *ev);
void mouseDoubleClickEvent(QMouseEvent *ev); void mouseDoubleClickEvent(QMouseEvent *ev);
void deleteBreakpoints(const QModelIndexList &list); void deleteBreakpoints(const BreakpointIds &ids);
void addBreakpoint(); void addBreakpoint();
void editBreakpoints(const QModelIndexList &list); void editBreakpoints(const BreakpointIds &ids);
void associateBreakpoint(const QModelIndexList &list, int thread); void associateBreakpoint(const BreakpointIds &ids, int thread);
void setBreakpointsEnabled(const QModelIndexList &list, bool enabled); void setBreakpointsEnabled(const BreakpointIds &ids, bool enabled);
void setBreakpointsFullPath(const QModelIndexList &list, bool fullpath);
bool m_alwaysResizeColumnsToContents; bool m_alwaysResizeColumnsToContents;
}; };

View File

@@ -210,6 +210,7 @@ struct DisassemblerViewAgentPrivate
QPointer<TextEditor::ITextEditor> editor; QPointer<TextEditor::ITextEditor> editor;
StackFrame frame; StackFrame frame;
bool tryMixed; bool tryMixed;
bool setMarker;
QPointer<DebuggerEngine> engine; QPointer<DebuggerEngine> engine;
LocationMark2 *locationMark; LocationMark2 *locationMark;
QHash<QString, QString> cache; QHash<QString, QString> cache;
@@ -219,6 +220,7 @@ struct DisassemblerViewAgentPrivate
DisassemblerViewAgentPrivate::DisassemblerViewAgentPrivate() : DisassemblerViewAgentPrivate::DisassemblerViewAgentPrivate() :
editor(0), editor(0),
tryMixed(true), tryMixed(true),
setMarker(true),
locationMark(new LocationMark2), locationMark(new LocationMark2),
mimeType(_("text/x-qtcreator-generic-asm")) mimeType(_("text/x-qtcreator-generic-asm"))
{ {
@@ -279,9 +281,11 @@ bool DisassemblerViewAgent::isMixed() const
&& d->frame.function != _("??"); && 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->frame = frame;
d->setMarker = setMarker;
d->tryMixed = tryMixed; d->tryMixed = tryMixed;
if (isMixed()) { if (isMixed()) {
QHash<QString, QString>::ConstIterator it = d->cache.find(frameKey(frame)); 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(); const int size = disassembly.size();
for (int lineNumber = 1; pos < size; lineNumber++) { for (int lineNumber = 1; pos < size; lineNumber++) {
int endOfLinePos = disassembly.indexOf(newLine, pos + 1); int endOfLinePos = disassembly.indexOf(newLine, pos);
if (endOfLinePos == -1) if (endOfLinePos == -1)
endOfLinePos = size; endOfLinePos = size;
const QString line = disassembly.mid(pos, endOfLinePos - pos); const QString line = disassembly.mid(pos, endOfLinePos - pos);
@@ -382,11 +386,14 @@ void DisassemblerViewAgent::setContents(const QString &contents)
plainTextEdit->setReadOnly(true); plainTextEdit->setReadOnly(true);
} }
if (d->setMarker)
d->editor->markableInterface()->removeMark(d->locationMark); d->editor->markableInterface()->removeMark(d->locationMark);
d->editor->setDisplayName(_("Disassembler (%1)").arg(d->frame.function)); 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) { if (lineNumberPos.first > 0) {
if (d->setMarker)
d->editor->markableInterface()->addMark(d->locationMark, lineNumberPos.first); d->editor->markableInterface()->addMark(d->locationMark, lineNumberPos.first);
if (plainTextEdit) { if (plainTextEdit) {
QTextCursor tc = plainTextEdit->textCursor(); QTextCursor tc = plainTextEdit->textCursor();
@@ -399,7 +406,6 @@ void DisassemblerViewAgent::setContents(const QString &contents)
bool DisassemblerViewAgent::contentsCoversAddress(const QString &contents) const bool DisassemblerViewAgent::contentsCoversAddress(const QString &contents) const
{ {
QTC_ASSERT(d, return false); QTC_ASSERT(d, return false);
return lineNumberOfAddress(contents, d->frame.address).first > 0; return lineNumberOfAddress(contents, d->frame.address).first > 0;
} }

View File

@@ -83,7 +83,7 @@ public:
explicit DisassemblerViewAgent(Debugger::DebuggerEngine *engine); explicit DisassemblerViewAgent(Debugger::DebuggerEngine *engine);
~DisassemblerViewAgent(); ~DisassemblerViewAgent();
void setFrame(const StackFrame &frame, bool tryMixed = true); void setFrame(const StackFrame &frame, bool tryMixed, bool setMarker);
const StackFrame &frame() const; const StackFrame &frame() const;
void resetLocation(); void resetLocation();
Q_SLOT void setContents(const QString &contents); Q_SLOT void setContents(const QString &contents);

View File

@@ -516,21 +516,15 @@ void DebuggerEngine::resetLocation()
void DebuggerEngine::gotoLocation(const QString &fileName, int lineNumber, bool setMarker) void DebuggerEngine::gotoLocation(const QString &fileName, int lineNumber, bool setMarker)
{ {
StackFrame frame; debuggerCore()->gotoLocation(fileName, lineNumber, setMarker);
frame.file = fileName;
frame.line = lineNumber;
gotoLocation(frame, setMarker);
} }
void DebuggerEngine::gotoLocation(const StackFrame &frame, bool setMarker) void DebuggerEngine::gotoLocation(const StackFrame &frame, bool setMarker)
{ {
if (debuggerCore()->boolSetting(OperateByInstruction) || !frame.isUsable()) { if (debuggerCore()->boolSetting(OperateByInstruction) || !frame.isUsable())
if (setMarker) d->m_disassemblerViewAgent.setFrame(frame, true, setMarker);
resetLocation(); else
d->m_disassemblerViewAgent.setFrame(frame);
} else {
debuggerCore()->gotoLocation(frame.file, frame.line, setMarker); debuggerCore()->gotoLocation(frame.file, frame.line, setMarker);
}
} }
// Called from RunControl. // Called from RunControl.

View File

@@ -395,9 +395,27 @@ const char * const SNAPSHOT_KEY = "Ctrl+D,Ctrl+S";
#endif #endif
} // namespace Constants } // namespace Constants
} // namespace Debugger
namespace Cdb {
void addCdb2OptionPages(QList<Core::IOptionsPage*> *);
} // namespace Cdb
namespace Internal {
// FIXME: Outdated?
// The createCdbEngine function takes a list of options pages it can add to.
// This allows for having a "enabled" toggle on the page independently
// of the engine. That's good for not enabling the related ActiveX control
// unnecessarily.
void addGdbOptionPages(QList<IOptionsPage*> *opts);
void addScriptOptionPages(QList<IOptionsPage*> *opts);
void addTcfOptionPages(QList<IOptionsPage*> *opts);
#ifdef CDB_ENABLED
void addCdbOptionPages(QList<IOptionsPage*> *opts);
#endif
static SessionManager *sessionManager() static SessionManager *sessionManager()
{ {
@@ -414,42 +432,19 @@ static QToolButton *toolButton(QAction *action)
// Retrieve file name and line and optionally address // Retrieve file name and line and optionally address
// from the data set on the text editor context menu action. // from the data set on the text editor context menu action.
static bool positionFromContextActionData(const QObject *sender, static bool positionFromContextActionData(const QObject *sender,
QString *fileName, QString *fileName, int *lineNumber, quint64 *address = 0)
int *lineNumber,
quint64 *address = 0)
{ {
if (const QAction *action = qobject_cast<const QAction *>(sender)) { const QAction *action = qobject_cast<const QAction *>(sender);
QTC_ASSERT(action, return false);
const QVariantList data = action->data().toList(); const QVariantList data = action->data().toList();
if (data.size() >= (address ? 3 : 2)) { QTC_ASSERT(data.size() == 3, return false);
*fileName = data.front().toString(); *fileName = data.front().toString();
*lineNumber = data.at(1).toInt(); *lineNumber = data.at(1).toInt();
if (address) if (address)
*address = data.at(2).toULongLong(); *address = data.at(2).toULongLong();
return true; return true;
}
}
return false;
} }
namespace Debugger {
namespace Cdb {
void addCdb2OptionPages(QList<Core::IOptionsPage*> *);
} // namespace Cdb
namespace Internal {
// FIXME: Outdated?
// The createCdbEngine function takes a list of options pages it can add to.
// This allows for having a "enabled" toggle on the page independently
// of the engine. That's good for not enabling the related ActiveX control
// unnecessarily.
void addGdbOptionPages(QList<IOptionsPage*> *opts);
void addScriptOptionPages(QList<IOptionsPage*> *opts);
void addTcfOptionPages(QList<IOptionsPage*> *opts);
#ifdef CDB_ENABLED
void addCdbOptionPages(QList<IOptionsPage*> *opts);
#endif
struct AttachRemoteParameters struct AttachRemoteParameters
{ {
AttachRemoteParameters() : attachPid(0), winCrashEvent(0) {} AttachRemoteParameters() : attachPid(0), winCrashEvent(0) {}
@@ -2391,7 +2386,9 @@ void DebuggerPluginPrivate::requestContextMenu(TextEditor::ITextEditor *editor,
QString line = editor->contents() QString line = editor->contents()
.section('\n', lineNumber - 1, lineNumber - 1); .section('\n', lineNumber - 1, lineNumber - 1);
BreakpointResponse needle; BreakpointResponse needle;
needle.type = BreakpointByAddress;
needle.address = DisassemblerViewAgent::addressFromDisassemblyLine(line); needle.address = DisassemblerViewAgent::addressFromDisassemblyLine(line);
address = needle.address;
needle.lineNumber = -1; needle.lineNumber = -1;
id = breakHandler()->findSimilarBreakpoint(needle); id = breakHandler()->findSimilarBreakpoint(needle);
} else { } else {

View File

@@ -1186,8 +1186,9 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
} }
// Quickly set the location marker. // Quickly set the location marker.
if (lineNumber && QFileInfo(fullName).exists()) if (lineNumber && !debuggerCore()->boolSetting(OperateByInstruction)
debuggerCore()->gotoLocation(fullName, lineNumber, true); && QFileInfo(fullName).exists())
gotoLocation(fullName, lineNumber, true);
if (!m_commandsToRunOnTemporaryBreak.isEmpty()) { if (!m_commandsToRunOnTemporaryBreak.isEmpty()) {
QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state()) QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state())
@@ -1443,7 +1444,7 @@ void GdbEngine::handleStop1(const GdbMi &data)
// //
// Stack // Stack
// //
reloadStack(false); reloadStack(false); // Will trigger register reload.
if (supportsThreads()) { if (supportsThreads()) {
int currentId = data.findChild("thread-id").data().toInt(); int currentId = data.findChild("thread-id").data().toInt();
@@ -1458,11 +1459,6 @@ void GdbEngine::handleStop1(const GdbMi &data)
CB(handleThreadInfo), currentId); CB(handleThreadInfo), currentId);
} }
} }
//
// Registers
//
reloadRegisters();
} }
void GdbEngine::handleInfoProc(const GdbResponse &response) void GdbEngine::handleInfoProc(const GdbResponse &response)
@@ -2886,8 +2882,7 @@ void GdbEngine::handleStackSelectThread(const GdbResponse &)
{ {
QTC_ASSERT(state() == InferiorUnrunnable || state() == InferiorStopOk, /**/); QTC_ASSERT(state() == InferiorUnrunnable || state() == InferiorStopOk, /**/);
showStatusMessage(tr("Retrieving data for stack view..."), 3000); showStatusMessage(tr("Retrieving data for stack view..."), 3000);
reloadRegisters(); reloadStack(true); // Will reload registers.
reloadStack(true);
updateLocals(); updateLocals();
} }
@@ -2943,6 +2938,7 @@ void GdbEngine::handleStackListFrames(const GdbResponse &response)
// ^error,data={msg="Previous frame identical to this frame (corrupt stack?)" // ^error,data={msg="Previous frame identical to this frame (corrupt stack?)"
// logstreamoutput="Previous frame identical to this frame (corrupt stack?)\n" // logstreamoutput="Previous frame identical to this frame (corrupt stack?)\n"
//qDebug() << "LISTING STACK FAILED: " << response.toString(); //qDebug() << "LISTING STACK FAILED: " << response.toString();
reloadRegisters();
return; return;
} }
@@ -4039,17 +4035,35 @@ void GdbEngine::handleFetchDisassemblerByCli(const GdbResponse &response)
// "Dump of assembler code from 0xb7ff598f to 0xb7ff5a07:" // "Dump of assembler code from 0xb7ff598f to 0xb7ff5a07:"
GdbMi output = response.data.findChild("consolestreamoutput"); GdbMi output = response.data.findChild("consolestreamoutput");
QByteArray res; QByteArray res;
QByteArray lastFunction;
foreach (const QByteArray &line0, output.data().split('\n')) { foreach (const QByteArray &line0, output.data().split('\n')) {
QByteArray line = line0.trimmed(); QByteArray line = line0.trimmed();
if (line.startsWith("=> ")) if (line.startsWith("=> "))
line = line.mid(3); line = line.mid(3);
if (line.isEmpty())
continue;
if (line.startsWith("Current language:")) if (line.startsWith("Current language:"))
continue; continue;
if (line.startsWith("Dump of assembler"))
continue;
if (line.startsWith("The current source")) if (line.startsWith("The current source"))
continue; continue;
if (line.startsWith("End of assembler")) if (line.startsWith("End of assembler"))
continue; continue;
if (line.startsWith("0x")) { 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(line);
res.append('\n'); res.append('\n');
continue; continue;

View File

@@ -162,7 +162,7 @@ void StackWindow::contextMenuEvent(QContextMenuEvent *ev)
(void) new MemoryViewAgent(currentEngine(), address); (void) new MemoryViewAgent(currentEngine(), address);
else if (act == actShowDisassembler) { else if (act == actShowDisassembler) {
DisassemblerViewAgent *agent = new DisassemblerViewAgent(engine); DisassemblerViewAgent *agent = new DisassemblerViewAgent(engine);
agent->setFrame(frame); agent->setFrame(frame, true, false);
} }
} }