Commit d8318a95 authored by hjk's avatar hjk
Browse files

debugger: refactor breakpoint handling

Use BreakpointData objects for communicaition instead of random
collection of some of their attributes.
parent 88e4917b
......@@ -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;
......
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