forked from qt-creator/qt-creator
debugger: refactor breakpoint handling
Use BreakpointData objects for communicaition instead of random collection of some of their attributes.
This commit is contained in:
@@ -112,7 +112,7 @@ public:
|
||||
return;
|
||||
|
||||
BreakHandler *handler = m_data->handler();
|
||||
handler->removeBreakpoint(handler->indexOf(m_data));
|
||||
handler->removeBreakpoint(m_data);
|
||||
handler->saveBreakpoints();
|
||||
handler->updateMarkers();
|
||||
}
|
||||
@@ -373,7 +373,9 @@ BreakpointData *BreakHandler::findSimilarBreakpoint(const BreakpointData &needle
|
||||
for (int index = 0; index != size(); ++index) {
|
||||
BreakpointData *data = m_bp[index];
|
||||
// Clear hit.
|
||||
if (data->bpNumber == needle.bpNumber)
|
||||
if (data->bpNumber == needle.bpNumber
|
||||
&& !data->bpNumber.isEmpty()
|
||||
&& data->bpNumber.toInt() != 0)
|
||||
return data;
|
||||
// Clear miss.
|
||||
if (data->type != needle.type)
|
||||
@@ -393,21 +395,6 @@ BreakpointData *BreakHandler::findSimilarBreakpoint(const BreakpointData &needle
|
||||
return 0;
|
||||
}
|
||||
|
||||
int BreakHandler::findBreakpoint(const QString &fileName, int lineNumber) const
|
||||
{
|
||||
if (lineNumber <= 0) {
|
||||
QByteArray address = fileName.toLatin1();
|
||||
for (int index = 0; index != size(); ++index)
|
||||
if (at(index)->bpAddress == address)
|
||||
return index;
|
||||
} else {
|
||||
for (int index = 0; index != size(); ++index)
|
||||
if (at(index)->isLocatedAt(fileName, lineNumber))
|
||||
return index;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
BreakpointData *BreakHandler::findBreakpointByNumber(int bpNumber) const
|
||||
{
|
||||
if (!size())
|
||||
@@ -790,6 +777,13 @@ void BreakHandler::removeBreakpoint(int index)
|
||||
saveBreakpoints();
|
||||
}
|
||||
|
||||
void BreakHandler::removeBreakpoint(BreakpointData *data)
|
||||
{
|
||||
removeBreakpointHelper(m_bp.indexOf(data));
|
||||
emit layoutChanged();
|
||||
saveBreakpoints();
|
||||
}
|
||||
|
||||
void BreakHandler::toggleBreakpointEnabled(BreakpointData *data)
|
||||
{
|
||||
QTC_ASSERT(data, return);
|
||||
|
||||
@@ -67,9 +67,8 @@ public:
|
||||
void removeAt(int index); // This also deletes the marker.
|
||||
void clear(); // This also deletes all the marker.
|
||||
int indexOf(BreakpointData *data) { return m_bp.indexOf(data); }
|
||||
// If lineNumber < 0, interpret fileName as address.
|
||||
int findBreakpoint(const QString &fileName, int lineNumber) const;
|
||||
BreakpointData *findSimilarBreakpoint(const BreakpointData &data) const;
|
||||
// Find a breakpoint matching approximately the data in needle.bp*,
|
||||
BreakpointData *findSimilarBreakpoint(const BreakpointData &needle) const;
|
||||
BreakpointData *findBreakpointByNumber(int bpNumber) const;
|
||||
void updateMarkers();
|
||||
|
||||
@@ -88,6 +87,7 @@ public slots:
|
||||
void toggleBreakpointEnabled(BreakpointData *data);
|
||||
void breakByFunction(const QString &functionName);
|
||||
void removeBreakpoint(int index);
|
||||
void removeBreakpoint(BreakpointData *data);
|
||||
|
||||
private:
|
||||
friend class BreakpointMarker;
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
|
||||
#include "breakwindow.h"
|
||||
|
||||
#include "breakhandler.h"
|
||||
#include "debuggeractions.h"
|
||||
#include "debuggermanager.h"
|
||||
#include "stackhandler.h"
|
||||
|
||||
@@ -885,61 +885,6 @@ void DebuggerManager::removeSnapshot(int index)
|
||||
d->m_snapshotHandler->removeSnapshot(index);
|
||||
}
|
||||
|
||||
BreakpointData *DebuggerManager::findBreakpoint(const QString &fileName, int lineNumber)
|
||||
{
|
||||
if (!d->m_breakHandler)
|
||||
return 0;
|
||||
int index = d->m_breakHandler->findBreakpoint(fileName, lineNumber);
|
||||
return index == -1 ? 0 : d->m_breakHandler->at(index);
|
||||
}
|
||||
|
||||
// FIXME: move further up the plugin where there's more specific context
|
||||
// information available.
|
||||
static BreakpointData *createBreakpointByFileAndLine
|
||||
(const QString &fileName, int lineNumber)
|
||||
{
|
||||
BreakpointData *data = new BreakpointData;
|
||||
if (lineNumber > 0) {
|
||||
data->fileName = fileName;
|
||||
data->lineNumber = QByteArray::number(lineNumber);
|
||||
data->pending = true;
|
||||
data->setMarkerFileName(fileName);
|
||||
data->setMarkerLineNumber(lineNumber);
|
||||
} else {
|
||||
data->funcName = fileName;
|
||||
data->lineNumber = 0;
|
||||
data->pending = true;
|
||||
// FIXME: Figure out in which disassembler view the Marker sits.
|
||||
// Might be better to let the user code create the BreakpointData
|
||||
// structure and insert it here.
|
||||
data->setMarkerFileName(QString());
|
||||
data->setMarkerLineNumber(0);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
void DebuggerManager::toggleBreakpoint(const QString &fileName, int lineNumber)
|
||||
{
|
||||
STATE_DEBUG(fileName << lineNumber);
|
||||
QTC_ASSERT(d->m_breakHandler, return);
|
||||
if (state() != InferiorRunning
|
||||
&& state() != InferiorStopped
|
||||
&& state() != DebuggerNotReady) {
|
||||
showStatusMessage(tr("Changing breakpoint state requires either a "
|
||||
"fully running or fully stopped application."));
|
||||
return;
|
||||
}
|
||||
|
||||
int index = d->m_breakHandler->findBreakpoint(fileName, lineNumber);
|
||||
if (index == -1)
|
||||
d->m_breakHandler->appendBreakpoint(
|
||||
createBreakpointByFileAndLine(fileName, lineNumber));
|
||||
else
|
||||
d->m_breakHandler->removeBreakpoint(index);
|
||||
|
||||
attemptBreakpointSynchronization();
|
||||
}
|
||||
|
||||
void DebuggerManager::attemptBreakpointSynchronization()
|
||||
{
|
||||
if (d->m_engine)
|
||||
@@ -1410,13 +1355,6 @@ void DebuggerManager::breakByFunction(const QString &functionName)
|
||||
attemptBreakpointSynchronization();
|
||||
}
|
||||
|
||||
void DebuggerManager::appendBreakpoint(BreakpointData *data)
|
||||
{
|
||||
QTC_ASSERT(d->m_breakHandler, return);
|
||||
d->m_breakHandler->appendBreakpoint(data);
|
||||
attemptBreakpointSynchronization();
|
||||
}
|
||||
|
||||
void DebuggerManager::setBusyCursor(bool busy)
|
||||
{
|
||||
//STATE_DEBUG("BUSY FROM: " << d->m_busy << " TO: " << d->m_busy);
|
||||
|
||||
@@ -289,7 +289,6 @@ public slots: // FIXME
|
||||
void reloadRegisters();
|
||||
void registerDockToggled(bool on);
|
||||
void clearStatusMessage();
|
||||
void appendBreakpoint(Internal::BreakpointData *data);
|
||||
void attemptBreakpointSynchronization();
|
||||
void reloadFullStack();
|
||||
void operateByInstructionTriggered();
|
||||
@@ -358,8 +357,7 @@ private:
|
||||
|
||||
void aboutToShutdown();
|
||||
|
||||
void toggleBreakpoint(const QString &fileName, int lineNumber);
|
||||
Internal::BreakpointData *findBreakpoint(const QString &fileName, int lineNumber);
|
||||
//void toggleBreakpoint(const QString &fileName, int lineNumber);
|
||||
void setToolTipExpression(const QPoint &mousePos,
|
||||
TextEditor::ITextEditor *editor, int cursorPos);
|
||||
void openTextEditor(const QString &titlePattern,
|
||||
|
||||
@@ -1146,19 +1146,28 @@ void DebuggerPlugin::requestContextMenu(TextEditor::ITextEditor *editor,
|
||||
if (!isDebuggable(editor))
|
||||
return;
|
||||
|
||||
QString fileName, position;
|
||||
BreakHandler *handler = m_manager->breakHandler();
|
||||
QTC_ASSERT(handler, return);
|
||||
|
||||
BreakpointData *data = 0;
|
||||
QString position;
|
||||
if (editor->property("DisassemblerView").toBool()) {
|
||||
QString fileName = editor->file()->fileName();
|
||||
QString line = editor->contents()
|
||||
.section('\n', lineNumber - 1, lineNumber - 1);
|
||||
fileName = line.left(line.indexOf(QLatin1Char(' ')));
|
||||
lineNumber = -1;
|
||||
position = _("*") + fileName;
|
||||
BreakpointData needle;
|
||||
needle.bpAddress = line.left(line.indexOf(QLatin1Char(' '))).toLatin1();
|
||||
needle.bpLineNumber = "-1";
|
||||
data = handler->findSimilarBreakpoint(needle);
|
||||
} else {
|
||||
fileName = editor->file()->fileName();
|
||||
QString fileName = editor->file()->fileName();
|
||||
position = fileName + QString(":%1").arg(lineNumber);
|
||||
BreakpointData needle;
|
||||
needle.bpFileName = fileName;
|
||||
needle.bpLineNumber = QByteArray::number(lineNumber);
|
||||
data = handler->findSimilarBreakpoint(needle);
|
||||
}
|
||||
BreakpointData *data = m_manager->findBreakpoint(fileName, lineNumber);
|
||||
|
||||
if (data) {
|
||||
// existing breakpoint
|
||||
@@ -1191,9 +1200,11 @@ void DebuggerPlugin::breakpointSetRemoveMarginActionTriggered()
|
||||
{
|
||||
QAction *act = qobject_cast<QAction *>(sender());
|
||||
QTC_ASSERT(act, return);
|
||||
BreakHandler *handler = m_manager->breakHandler();
|
||||
QTC_ASSERT(handler, return);
|
||||
QString str = act->data().toString();
|
||||
int pos = str.lastIndexOf(':');
|
||||
m_manager->toggleBreakpoint(str.left(pos), str.mid(pos + 1).toInt());
|
||||
toggleBreakpoint(str, pos);
|
||||
}
|
||||
|
||||
void DebuggerPlugin::breakpointEnableDisableMarginActionTriggered()
|
||||
@@ -1205,12 +1216,12 @@ void DebuggerPlugin::breakpointEnableDisableMarginActionTriggered()
|
||||
|
||||
QString str = act->data().toString();
|
||||
int pos = str.lastIndexOf(':');
|
||||
QString fileName = str.left(pos);
|
||||
int lineNumber = str.mid(pos + 1).toInt();
|
||||
|
||||
BreakpointData *data = handler->at(handler->findBreakpoint(fileName, lineNumber));
|
||||
BreakpointData needle;
|
||||
needle.bpFileName = str.left(pos);
|
||||
needle.bpLineNumber = str.mid(pos + 1).toLatin1();
|
||||
BreakpointData *data = handler->findSimilarBreakpoint(needle);
|
||||
QTC_ASSERT(data, return);
|
||||
handler->toggleBreakpointEnabled(data);
|
||||
|
||||
m_manager->attemptBreakpointSynchronization();
|
||||
}
|
||||
|
||||
@@ -1218,7 +1229,7 @@ void DebuggerPlugin::requestMark(ITextEditor *editor, int lineNumber)
|
||||
{
|
||||
if (!isDebuggable(editor))
|
||||
return;
|
||||
m_manager->toggleBreakpoint(editor->file()->fileName(), lineNumber);
|
||||
toggleBreakpoint(editor->file()->fileName(), lineNumber);
|
||||
}
|
||||
|
||||
void DebuggerPlugin::showToolTip(ITextEditor *editor, const QPoint &point, int pos)
|
||||
@@ -1532,14 +1543,58 @@ void DebuggerPlugin::enableReverseDebuggingTriggered(const QVariant &value)
|
||||
m_manager->debuggerManagerActions().reverseDirectionAction->setChecked(false);
|
||||
}
|
||||
|
||||
static BreakpointData *createBreakpointByFileAndLine
|
||||
(const QString &fileName, int lineNumber)
|
||||
{
|
||||
BreakpointData *data = new BreakpointData;
|
||||
if (lineNumber > 0) {
|
||||
data->fileName = fileName;
|
||||
data->lineNumber = QByteArray::number(lineNumber);
|
||||
data->pending = true;
|
||||
data->setMarkerFileName(fileName);
|
||||
data->setMarkerLineNumber(lineNumber);
|
||||
} else {
|
||||
data->funcName = fileName;
|
||||
data->lineNumber = 0;
|
||||
data->pending = true;
|
||||
// FIXME: Figure out in which disassembler view the Marker sits.
|
||||
// Might be better to let the user code create the BreakpointData
|
||||
// structure and insert it here.
|
||||
data->setMarkerFileName(QString());
|
||||
data->setMarkerLineNumber(0);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
void DebuggerPlugin::toggleBreakpoint()
|
||||
{
|
||||
ITextEditor *textEditor = currentTextEditor();
|
||||
QTC_ASSERT(textEditor, return);
|
||||
QString fileName = textEditor->file()->fileName();
|
||||
int lineNumber = textEditor->currentLine();
|
||||
if (lineNumber >= 0)
|
||||
m_manager->toggleBreakpoint(fileName, lineNumber);
|
||||
toggleBreakpoint(textEditor->file()->fileName(), lineNumber);
|
||||
}
|
||||
|
||||
void DebuggerPlugin::toggleBreakpoint(const QString &fileName, int lineNumber)
|
||||
{
|
||||
BreakHandler *handler = m_manager->breakHandler();
|
||||
QTC_ASSERT(handler, return);
|
||||
BreakpointData needle;
|
||||
needle.bpFileName = fileName;
|
||||
needle.bpLineNumber.setNum(lineNumber);
|
||||
BreakpointData *data = handler->findSimilarBreakpoint(needle);
|
||||
if (data) {
|
||||
handler->removeBreakpoint(data);
|
||||
} else {
|
||||
data = new BreakpointData;
|
||||
data->fileName = fileName;
|
||||
data->lineNumber = QByteArray::number(lineNumber);
|
||||
data->pending = true;
|
||||
data->setMarkerFileName(fileName);
|
||||
data->setMarkerLineNumber(lineNumber);
|
||||
handler->appendBreakpoint(data);
|
||||
}
|
||||
m_manager->attemptBreakpointSynchronization();
|
||||
}
|
||||
|
||||
void DebuggerPlugin::attachRemoteTcf()
|
||||
|
||||
@@ -82,10 +82,10 @@ public:
|
||||
~DebuggerPlugin();
|
||||
|
||||
private:
|
||||
virtual bool initialize(const QStringList &arguments, QString *error_message);
|
||||
virtual void aboutToShutdown();
|
||||
virtual void extensionsInitialized();
|
||||
virtual void remoteCommand(const QStringList &options, const QStringList &arguments);
|
||||
bool initialize(const QStringList &arguments, QString *error_message);
|
||||
void aboutToShutdown();
|
||||
void extensionsInitialized();
|
||||
void remoteCommand(const QStringList &options, const QStringList &arguments);
|
||||
|
||||
QVariant configValue(const QString &name) const;
|
||||
TextEditor::ITextEditor *currentTextEditor();
|
||||
@@ -96,8 +96,8 @@ private:
|
||||
private slots:
|
||||
void activatePreviousMode();
|
||||
void activateDebugMode();
|
||||
void editorOpened(Core::IEditor *);
|
||||
void editorAboutToClose(Core::IEditor *);
|
||||
void editorOpened(Core::IEditor *editor);
|
||||
void editorAboutToClose(Core::IEditor *editor);
|
||||
void handleStateChanged(int state);
|
||||
void requestMark(TextEditor::ITextEditor *editor, int lineNumber);
|
||||
void showToolTip(TextEditor::ITextEditor *editor, const QPoint &pnt, int pos);
|
||||
@@ -105,11 +105,12 @@ private slots:
|
||||
int lineNumber, QMenu *menu);
|
||||
|
||||
void resetLocation();
|
||||
void gotoLocation(const QString &file, int line, bool setMarker);
|
||||
void gotoLocation(const QString &fileName, int lineNumber, bool setMarker);
|
||||
|
||||
void openTextEditor(const QString &titlePattern, const QString &contents);
|
||||
|
||||
void toggleBreakpoint();
|
||||
void toggleBreakpoint(const QString &fileName, int lineNumber);
|
||||
void breakpointSetRemoveMarginActionTriggered();
|
||||
void breakpointEnableDisableMarginActionTriggered();
|
||||
void onModeChanged(Core::IMode *mode);
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "watchhandler.h"
|
||||
|
||||
#include "breakpoint.h"
|
||||
#include "breakhandler.h"
|
||||
#include "debuggeractions.h"
|
||||
#include "debuggeragents.h"
|
||||
#include "debuggerdialogs.h"
|
||||
@@ -371,7 +372,8 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
|
||||
BreakpointData *data = new BreakpointData;
|
||||
data->type = BreakpointData::WatchpointType;
|
||||
data->address = address.toLatin1();
|
||||
m_manager->appendBreakpoint(data);
|
||||
m_manager->breakHandler()->appendBreakpoint(data);
|
||||
m_manager->attemptBreakpointSynchronization();
|
||||
} else if (act == actSelectWidgetToWatch) {
|
||||
grabMouse(Qt::CrossCursor);
|
||||
m_grabbing = true;
|
||||
|
||||
Reference in New Issue
Block a user