OSDN Git Service

debugger: display "sub-breakpoints"
authorhjk <qtc-committer@nokia.com>
Wed, 15 Jun 2011 12:02:26 +0000 (14:02 +0200)
committerhjk <qthjk@ovi.com>
Mon, 20 Jun 2011 09:34:22 +0000 (11:34 +0200)
<MULTIPLE> happens in constructors, inline functions, and
at other places like 'foreach' lines.

Change-Id: Ifb89b659d279f257ba8295b80a35d605820ec54b
Reviewed-on: http://codereview.qt.nokia.com/498
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: hjk <qthjk@ovi.com>
14 files changed:
src/plugins/debugger/breakhandler.cpp
src/plugins/debugger/breakhandler.h
src/plugins/debugger/breakpoint.cpp
src/plugins/debugger/breakpoint.h
src/plugins/debugger/breakwindow.cpp
src/plugins/debugger/cdb/cdbengine.cpp
src/plugins/debugger/cdb/cdbparsehelpers.cpp
src/plugins/debugger/debugger.pro
src/plugins/debugger/debuggerengine.cpp
src/plugins/debugger/debuggerplugin.cpp
src/plugins/debugger/gdb/gdbengine.cpp
src/plugins/debugger/gdb/gdbengine.h
src/plugins/debugger/lldb/ipcenginehost.cpp
src/plugins/debugger/watchhandler.cpp

index 8cd2bf5..359af3e 100644 (file)
 
 #include <utils/qtcassert.h>
 
+#if USE_BREAK_MODEL_TEST
+#include "modeltest.h"
+#endif
+
 #include <QtCore/QDir>
 #include <QtCore/QFileInfo>
 #include <QtCore/QTimerEvent>
@@ -126,7 +130,11 @@ static QString typeToString(BreakpointType type)
 
 BreakHandler::BreakHandler()
   : m_syncTimerId(-1)
-{}
+{
+#if USE_BREAK_MODEL_TEST
+    new ModelTest(this, 0);
+#endif
+}
 
 BreakHandler::~BreakHandler()
 {}
@@ -169,16 +177,6 @@ QIcon BreakHandler::emptyIcon()
     return icon;
 }
 
-int BreakHandler::columnCount(const QModelIndex &parent) const
-{
-    return parent.isValid() ? 0 : 8;
-}
-
-int BreakHandler::rowCount(const QModelIndex &parent) const
-{
-    return parent.isValid() ? 0 : m_storage.size();
-}
-
 static inline bool fileNameMatch(const QString &f1, const QString &f2)
 {
 #ifdef Q_OS_WIN
@@ -431,12 +429,9 @@ QVariant BreakHandler::headerData(int section,
 
 BreakpointId BreakHandler::findBreakpointByIndex(const QModelIndex &index) const
 {
-    int r = index.row();
-    ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd();
-    for (int i = 0; it != et; ++it, ++i)
-        if (i == r)
-            return it.key();
-    return BreakpointId();
+    //qDebug() << "FIND: " << index <<
+    //    BreakpointId::fromInternalId(index.internalId());
+    return BreakpointId::fromInternalId(index.internalId());
 }
 
 BreakpointIds BreakHandler::findBreakpointsByIndex(const QList<QModelIndex> &list) const
@@ -469,15 +464,72 @@ int BreakHandler::threadSpecFromDisplay(const QString &str)
     return ok ? result : -1;
 }
 
-QModelIndex BreakHandler::index(int row, int col, const QModelIndex &parent) const
+QModelIndex BreakHandler::createIndex(int row, int column, quint32 id) const
 {
-    Q_UNUSED(parent);
-    return createIndex(row, col, 0);
+    return QAbstractItemModel::createIndex(row, column, id);
 }
 
-QModelIndex BreakHandler::parent(const QModelIndex &parent) const
+QModelIndex BreakHandler::createIndex(int row, int column, void *ptr) const
 {
-    Q_UNUSED(parent);
+    QTC_ASSERT(false, /**/); // This function is not used.
+    return QAbstractItemModel::createIndex(row, column, ptr);
+}
+
+int BreakHandler::columnCount(const QModelIndex &idx) const
+{
+    if (idx.column() > 0)
+        return 0;
+    const BreakpointId id = findBreakpointByIndex(idx);
+    return id.isMinor() ? 0 : 8;
+}
+
+int BreakHandler::rowCount(const QModelIndex &idx) const
+{
+    if (idx.column() > 0)
+        return 0;
+    if (!idx.isValid())
+        return m_storage.size();
+    const BreakpointId id = findBreakpointByIndex(idx);
+    if (id.isMajor())
+        return m_storage.value(id).subItems.size();
+    return 0;
+}
+
+QModelIndex BreakHandler::index(int row, int col, const QModelIndex &parent) const
+{
+    if (row < 0 || col < 0)
+        return QModelIndex();
+    if (parent.column() > 0)
+        return QModelIndex();
+    BreakpointId id = findBreakpointByIndex(parent);
+    if (id.isMajor()) {
+        ConstIterator it = m_storage.find(id);
+        if (row >= it->subItems.size())
+            return QModelIndex();
+        BreakpointId sub = id.child(row);
+        return createIndex(row, col, sub.toInternalId());
+    }
+    if (id.isMinor())
+        return QModelIndex();
+    QTC_ASSERT(!id.isValid(), return QModelIndex());
+    if (row >= m_storage.size())
+        return QModelIndex();
+    id = at(row);
+    return createIndex(row, col, id.toInternalId());
+}
+
+QModelIndex BreakHandler::parent(const QModelIndex &idx) const
+{
+    if (!idx.isValid())
+        return QModelIndex();
+    BreakpointId id = findBreakpointByIndex(idx);
+    if (id.isMajor())
+        return QModelIndex();
+    if (id.isMinor()) {
+        BreakpointId pid = id.parent();
+        int row = indexOf(pid);
+        return createIndex(row, 0, pid.toInternalId());
+    }
     return QModelIndex();
 }
 
@@ -489,9 +541,13 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
         return QVariant();
 
     BreakpointId id = findBreakpointByIndex(mi);
-    //qDebug() << "DATA: " << id << role << mi.column();
-    ConstIterator it = m_storage.find(id);
-    BREAK_ASSERT(it != m_storage.end(), return QVariant());
+
+    BreakpointId pid = id;
+    if (id.isMinor())
+        pid = id.parent();
+
+    ConstIterator it = m_storage.find(pid);
+    QTC_ASSERT(it != m_storage.end(), return QVariant());
     const BreakpointParameters &data = it->data;
     const BreakpointResponse &response = it->response;
 
@@ -511,10 +567,24 @@ QVariant BreakHandler::data(const QModelIndex &mi, int role) const
             break;
     };
 
+    if (id.isMinor()) {
+        QTC_ASSERT(id.minorPart() <= it->subItems.size(), return QVariant());
+        const BreakpointResponse &res = it->subItems.at(id.minorPart() - 1);
+        switch (mi.column()) {
+        case 0:
+            if (role == Qt::DisplayRole)
+                return id.toString();
+        case 1:
+            if (role == Qt::DisplayRole)
+                return res.functionName;
+        }
+        return QVariant();
+    }
+
     switch (mi.column()) {
         case 0:
             if (role == Qt::DisplayRole) {
-                return QString::number(id);
+                return id.toString();
                 //return QString("%1 - %2").arg(id).arg(response.number);
             }
             if (role == Qt::DecorationRole)
@@ -894,6 +964,7 @@ void BreakHandler::notifyBreakpointReleased(BreakpointId id)
     it->state = BreakpointNew;
     it->engine = 0;
     it->response = BreakpointResponse();
+    it->subItems.clear();
     delete it->marker;
     it->marker = 0;
     if (it->data.type == WatchpointAtAddress
@@ -937,8 +1008,8 @@ void BreakHandler::removeBreakpoint(BreakpointId id)
         cleanupBreakpoint(id);
         break;
     default:
-        qWarning("Warning: Cannot remove breakpoint %llu in state '%s'.",
-               id, qPrintable(stateToString(it->state)));
+        qWarning("Warning: Cannot remove breakpoint %s in state '%s'.",
+               qPrintable(id.toString()), qPrintable(stateToString(it->state)));
         it->state = BreakpointRemoveRequested;
         break;
     }
@@ -963,9 +1034,42 @@ void BreakHandler::appendBreakpoint(const BreakpointParameters &data)
     m_storage.insert(id, item);
     endInsertRows();
 
+    layoutChanged();
+
     updateMarker(id);
     scheduleSynchronization();
+}
 
+BreakpointId BreakHandler::at(int n) const
+{
+    if (n < 0 || n >= m_storage.size())
+        return BreakpointId();
+    ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd();
+    for ( ; --n >= 0; ++it)
+        ;
+    return it.key();
+}
+
+int BreakHandler::indexOf(BreakpointId id) const
+{
+    int row = 0;
+    ConstIterator it = m_storage.constBegin(), et = m_storage.constEnd();
+    for ( ; it != et; ++it, ++row)
+        if (it.key() == id)
+            return row;
+    return -1;
+}
+
+void BreakHandler::appendSubBreakpoint(BreakpointId id, const BreakpointResponse &data)
+{
+    Iterator it = m_storage.find(id);
+    QTC_ASSERT(it != m_storage.end(), return);
+    int row = indexOf(id);
+    QTC_ASSERT(row != -1, return);
+    QModelIndex idx = createIndex(row, 0, id.toInternalId());
+    beginInsertRows(idx, it->subItems.size(), it->subItems.size());
+    it->subItems.append(data);
+    endInsertRows();
 }
 
 void BreakHandler::saveSessionData()
index d7ed279..695a56f 100644 (file)
@@ -70,6 +70,7 @@ public:
 
     // The only way to add a new breakpoint.
     void appendBreakpoint(const BreakpointParameters &data);
+    void appendSubBreakpoint(BreakpointId id, const BreakpointResponse &data);
 
     BreakpointIds allBreakpointIds() const;
     BreakpointIds engineBreakpointIds(DebuggerEngine *engine) const;
@@ -169,7 +170,11 @@ private:
     Qt::ItemFlags flags(const QModelIndex &index) const;
     QModelIndex index(int row, int col, const QModelIndex &parent) const;
     QModelIndex parent(const QModelIndex &parent) const;
+    QModelIndex createIndex(int row, int column, quint32 id) const;
+    QModelIndex createIndex(int row, int column, void *ptr) const;
 
+    int indexOf(BreakpointId id) const;
+    BreakpointId at(int index) const;
     bool isEngineRunning(BreakpointId id) const;
     void setState(BreakpointId id, BreakpointState state);
     void loadBreakpoints();
@@ -195,6 +200,7 @@ private:
         DebuggerEngine *engine;  // Engine currently handling the breakpoint.
         BreakpointResponse response;
         BreakpointMarker *marker;
+        QList<BreakpointResponse> subItems;
     };
     typedef QHash<BreakpointId, BreakpointItem> BreakpointStorage;
     typedef BreakpointStorage::ConstIterator ConstIterator;
index 70d75db..6b48be3 100644 (file)
@@ -32,6 +32,8 @@
 
 #include "breakpoint.h"
 
+#include "utils/qtcassert.h"
+
 #include <QtCore/QByteArray>
 #include <QtCore/QDebug>
 
@@ -40,6 +42,39 @@ namespace Internal {
 
 //////////////////////////////////////////////////////////////////
 //
+// BreakpointId
+//
+//////////////////////////////////////////////////////////////////
+
+QDebug operator<<(QDebug d, const BreakpointId &id)
+{
+    d << qPrintable(id.toString());
+    return d;
+}
+
+QString BreakpointId::toString() const
+{
+    if (!isValid())
+        return "<invalid bkpt>";
+    if (isMinor())
+        return QString("%1.%2").arg(m_majorPart).arg(m_minorPart);
+    return QString::number(m_majorPart);
+}
+
+BreakpointId BreakpointId::parent() const
+{
+    QTC_ASSERT(isMinor(), return BreakpointId());
+    return BreakpointId(m_majorPart, 0);
+}
+
+BreakpointId BreakpointId::child(int row) const
+{
+    QTC_ASSERT(isMajor(), return BreakpointId());
+    return BreakpointId(m_majorPart, row + 1);
+}
+
+//////////////////////////////////////////////////////////////////
+//
 // BreakpointParameters
 //
 //////////////////////////////////////////////////////////////////
@@ -163,24 +198,34 @@ QString BreakpointParameters::toString() const
 */
 
 BreakpointResponse::BreakpointResponse()
-    : number(0), pending(true), multiple(false), correctedLineNumber(0)
-{}
+{
+    number = 0;
+    subNumber = 0;
+    pending = true;
+    multiple = false;
+    correctedLineNumber = 0;
+}
 
 QString BreakpointResponse::toString() const
 {
     QString result = BreakpointParameters::toString();
     QTextStream ts(&result);
     ts << " Number: " << number;
+    if (subNumber)
+        ts << "." << subNumber;
     if (pending)
         ts << " [pending]";
     if (!fullName.isEmpty())
         ts << " FullName: " << fullName;
+    if (!functionName.isEmpty())
+        ts << " Function: " << functionName;
     if (multiple)
         ts << " Multiple: " << multiple;
     if (!extra.isEmpty())
         ts << " Extra: " << extra;
     if (correctedLineNumber)
         ts << " CorrectedLineNumber: " << correctedLineNumber;
+    ts << ' ';
     return result + BreakpointParameters::toString();
 }
 
@@ -188,6 +233,7 @@ void BreakpointResponse::fromParameters(const BreakpointParameters &p)
 {
     BreakpointParameters::operator=(p);
     number = 0;
+    subNumber = 0;
     fullName.clear();
     multiple = false;
     extra.clear();
index c922684..e9780a7 100644 (file)
@@ -33,6 +33,7 @@
 #ifndef DEBUGGER_BREAKPOINT_H
 #define DEBUGGER_BREAKPOINT_H
 
+#include <QtCore/QDebug>
 #include <QtCore/QList>
 #include <QtCore/QMetaType>
 #include <QtCore/QString>
 namespace Debugger {
 namespace Internal {
 
-typedef quint64 BreakpointId;
+class BreakpointId
+{
+public:
+    BreakpointId() { m_majorPart = m_minorPart = 0; }
+    explicit BreakpointId(quint16 ma) { m_majorPart = ma; m_minorPart = 0; }
+    BreakpointId(quint16 ma, quint16 mi) { m_majorPart = ma; m_minorPart = mi; }
+
+    bool isValid() const { return m_majorPart != 0; }
+    bool isMajor() const { return m_majorPart != 0 && m_minorPart == 0; }
+    bool isMinor() const { return m_majorPart != 0 && m_minorPart != 0; }
+    bool operator!() const { return !isValid(); }
+    operator const void*() const { return isValid() ? this : 0; }
+    quint32 toInternalId() const { return m_majorPart | (m_minorPart << 16); }
+    QString toString() const;
+    bool operator==(const BreakpointId &id) const
+        { return m_majorPart == id.m_majorPart && m_minorPart == id.m_minorPart; }
+    quint16 majorPart() const { return m_majorPart; }
+    quint16 minorPart() const { return m_minorPart; }
+    BreakpointId parent() const;
+    BreakpointId child(int row) const;
+
+    static BreakpointId fromInternalId(quint32 id)
+        { return BreakpointId(id & 0xff, id >> 16); }
+
+private:
+    quint16 m_majorPart;
+    quint16 m_minorPart;
+};
+
+QDebug operator<<(QDebug d, const BreakpointId &id);
 
 //////////////////////////////////////////////////////////////////
 //
@@ -165,6 +195,7 @@ public:
     void fromParameters(const BreakpointParameters &p);
 
     int number;             //!< Breakpoint number assigned by the debugger engine.
+    int subNumber;          //!< Breakpoint sub-number assigned by the engine.
     bool pending;           //!< Breakpoint not fully resolved.
     QString fullName;       //!< Full file name acknowledged by the debugger engine.
     bool multiple;          //!< Happens in constructors/gdb.
@@ -175,7 +206,15 @@ public:
 
 typedef QList<BreakpointId> BreakpointIds;
 
+inline uint qHash(const Debugger::Internal::BreakpointId &id)
+{
+    return id.toInternalId();
+}
+
 } // namespace Internal
 } // namespace Debugger
 
+Q_DECLARE_METATYPE(Debugger::Internal::BreakpointId)
+
+
 #endif // DEBUGGER_BREAKPOINT_H
index 8aabf37..c832a3d 100644 (file)
@@ -524,6 +524,7 @@ void BreakWindow::setModel(QAbstractItemModel *model)
     resizeColumnToContents(0); // Number
     resizeColumnToContents(3); // Line
     resizeColumnToContents(6); // Ignore count
+    connect(model, SIGNAL(layoutChanged()), this, SLOT(expandAll()));
 }
 
 void BreakWindow::contextMenuEvent(QContextMenuEvent *ev)
index 7005b00..f990351 100644 (file)
@@ -192,7 +192,7 @@ struct MemoryChangeCookie
 
 struct ConditionalBreakPointCookie
 {
-    ConditionalBreakPointCookie(BreakpointId i = 0) : id(i) {}
+    ConditionalBreakPointCookie(BreakpointId i = BreakpointId()) : id(i) {}
     BreakpointId id;
     GdbMi stopReason;
 };
@@ -1817,7 +1817,7 @@ static inline QString msgTracePointTriggered(BreakpointId id, const int number,
                                              const QString &threadId)
 {
     return CdbEngine::tr("Trace point %1 (%2) in thread %3 triggered.")
-            .arg(id).arg(number).arg(threadId);
+            .arg(id.toString()).arg(number).arg(threadId);
 }
 
 static inline QString msgCheckingConditionalBreakPoint(BreakpointId id, const int number,
@@ -1825,7 +1825,7 @@ static inline QString msgCheckingConditionalBreakPoint(BreakpointId id, const in
                                                        const QString &threadId)
 {
     return CdbEngine::tr("Conditional breakpoint %1 (%2) in thread %3 triggered, examining expression '%4'.")
-            .arg(id).arg(number).arg(threadId, QString::fromAscii(condition));
+            .arg(id.toString()).arg(number).arg(threadId, QString::fromAscii(condition));
 }
 
 unsigned CdbEngine::examineStopReason(const GdbMi &stopReason,
@@ -1856,11 +1856,11 @@ unsigned CdbEngine::examineStopReason(const GdbMi &stopReason,
     if (reason == "breakpoint") {
         // Note: Internal breakpoints (run to line) are reported with id=0.
         // Step out creates temporary breakpoints with id 10000.
-        BreakpointId id = 0;
+        BreakpointId id;
         int number = 0;
         const GdbMi breakpointIdG = stopReason.findChild("breakpointId");
         if (breakpointIdG.isValid()) {
-            id = breakpointIdG.data().toULongLong();
+            id = BreakpointId(breakpointIdG.data().toInt());
             if (id && breakHandler()->engineBreakpointIds(this).contains(id)) {
                 const BreakpointResponse parameters =  breakHandler()->response(id);
                 // Trace point? Just report.
@@ -1879,7 +1879,7 @@ unsigned CdbEngine::examineStopReason(const GdbMi &stopReason,
                     return StopReportLog;
                 }
             } else {
-                id = 0;
+                id = BreakpointId();
             }
         }
         QString tid = QString::number(threadId);
@@ -2526,7 +2526,7 @@ void CdbEngine::attemptBreakpointSynchronization()
                 postCommand(cdbAddBreakpointCommand(parameters, m_sourcePathMappings, id, false), 0);
             }
             if (!parameters.enabled)
-                postCommand("bd " + QByteArray::number(id), 0);
+                postCommand("bd " + QByteArray::number(id.majorPart()), 0);
             handler->notifyBreakpointInsertProceeding(id);
             handler->notifyBreakpointInsertOk(id);
             m_pendingBreakpointMap.insert(id, response);
@@ -2534,30 +2534,33 @@ void CdbEngine::attemptBreakpointSynchronization()
             // Ensure enabled/disabled is correct in handler and line number is there.
             handler->setResponse(id, response);
             if (debugBreakpoints)
-                qDebug("Adding %llu %s\n", id, qPrintable(response.toString()));
+                qDebug("Adding %d %s\n", id.toInternalId(),
+                    qPrintable(response.toString()));
             break;
         case BreakpointChangeRequested:
             handler->notifyBreakpointChangeProceeding(id);
             if (debugBreakpoints)
-                qDebug("Changing %llu:\n    %s\nTo %s\n", id, qPrintable(handler->response(id).toString()),
-                       qPrintable(parameters.toString()));
+                qDebug("Changing %d:\n    %s\nTo %s\n", id.toInternalId(),
+                    qPrintable(handler->response(id).toString()),
+                    qPrintable(parameters.toString()));
             if (parameters.enabled != handler->response(id).enabled) {
                 // Change enabled/disabled breakpoints without triggering update.
-                postCommand((parameters.enabled ? "be " : "bd ") + QByteArray::number(id), 0);
+                postCommand((parameters.enabled ? "be " : "bd ")
+                    + QByteArray::number(id.majorPart()), 0);
                 response.pending = false;
                 response.enabled = parameters.enabled;
                 handler->setResponse(id, response);
             } else {
                 // Delete and re-add, triggering update
                 addedChanged = true;
-                postCommand("bc " + QByteArray::number(id), 0);
+                postCommand("bc " + QByteArray::number(id.majorPart()), 0);
                 postCommand(cdbAddBreakpointCommand(parameters, m_sourcePathMappings, id, false), 0);
                 m_pendingBreakpointMap.insert(id, response);
             }
             handler->notifyBreakpointChangeOk(id);
             break;
         case BreakpointRemoveRequested:
-            postCommand("bc " + QByteArray::number(id), 0);
+            postCommand("bc " + QByteArray::number(id.majorPart()), 0);
             handler->notifyBreakpointRemoveProceeding(id);
             handler->notifyBreakpointRemoveOk(id);
             m_pendingBreakpointMap.remove(id);
@@ -2689,9 +2692,9 @@ void CdbEngine::handleExpression(const CdbExtensionCommandPtr &command)
         const ConditionalBreakPointCookie cookie = qvariant_cast<ConditionalBreakPointCookie>(command->cookie);
         const QString message = value ?
             tr("Value %1 obtained from evaluating the condition of breakpoint %2, stopping.").
-            arg(value).arg(cookie.id) :
+            arg(value).arg(cookie.id.toString()) :
             tr("Value 0 obtained from evaluating the condition of breakpoint %1, continuing.").
-            arg(cookie.id);
+            arg(cookie.id.toString());
         showMessage(message, LogMisc);
         // Stop if evaluation is true, else continue
         if (value) {
@@ -2828,8 +2831,9 @@ void CdbEngine::handleBreakPoints(const GdbMi &value)
         BreakpointResponse reportedResponse;
         const BreakpointId id = parseBreakPoint(breakPointG, &reportedResponse);
         if (debugBreakpoints)
-            qDebug("  Parsed %llu: pending=%d %s\n", id, reportedResponse.pending,
-                   qPrintable(reportedResponse.toString()));
+            qDebug("  Parsed %d: pending=%d %s\n", id.majorPart(),
+                reportedResponse.pending,
+                qPrintable(reportedResponse.toString()));
 
         if (!reportedResponse.pending) {
             const PendingBreakPointMap::iterator it = m_pendingBreakpointMap.find(id);
@@ -2843,7 +2847,8 @@ void CdbEngine::handleBreakPoints(const GdbMi &value)
                 currentResponse.enabled = reportedResponse.enabled;
                 formatCdbBreakPointResponse(id, currentResponse, str);
                 if (debugBreakpoints)
-                    qDebug("  Setting for %llu: %s\n", id, qPrintable(currentResponse.toString()));
+                    qDebug("  Setting for %d: %s\n", id.majorPart(),
+                        qPrintable(currentResponse.toString()));
                 handler->setResponse(id, currentResponse);
                 m_pendingBreakpointMap.erase(it);
             }
index 0793f2f..d3ed8de 100644 (file)
@@ -135,7 +135,7 @@ static BreakpointParameters fixWinMSVCBreakpoint(const BreakpointParameters &p)
 
 QByteArray cdbAddBreakpointCommand(const BreakpointParameters &bpIn,
                                    const QList<QPair<QString, QString> > &sourcePathMapping,
-                                   BreakpointId id /* = BreakpointId(-1) */,
+                                   BreakpointId id /* = BreakpointId() */,
                                    bool oneshot)
 {
     const BreakpointParameters bp = fixWinMSVCBreakpoint(bpIn);
@@ -149,8 +149,8 @@ QByteArray cdbAddBreakpointCommand(const BreakpointParameters &bpIn,
     // is kept when reporting back breakpoints (which is otherwise discarded
     // when resolving).
     str << (bp.type == WatchpointAtAddress ? "ba" : "bu");
-    if (id != BreakpointId(-1))
-        str << id;
+    if (id.isValid())
+        str << id.toString();
     str << ' ';
     if (oneshot)
         str << "/1 ";
@@ -308,7 +308,7 @@ BreakpointId parseBreakPoint(const GdbMi &gdbmi, BreakpointResponse *r,
     const GdbMi idG = gdbmi.findChild("id");
     if (idG.isValid()) { // Might not be valid if there is not id
         bool ok;
-        const BreakpointId cid = idG.data().toULongLong(&ok);
+        const BreakpointId cid(idG.data().toInt(&ok));
         if (ok)
             id = cid;
     }
index 57e9586..68b5fcf 100644 (file)
@@ -123,10 +123,11 @@ FORMS += attachexternaldialog.ui \
 
 RESOURCES += debugger.qrc
 
-false {
+true {
     SOURCES += $$PWD/modeltest.cpp
     HEADERS += $$PWD/modeltest.h
-    DEFINES += USE_MODEL_TEST=1
+    #DEFINES += USE_WATCH_MODEL_TEST=1
+    #DEFINES += USE_BREAK_MODEL_TEST=1
 }
 win32 {
 include(../../shared/registryaccess/registryaccess.pri)
index 8120ed0..ed4c584 100644 (file)
@@ -1497,7 +1497,7 @@ QString DebuggerEngine::msgWatchpointByExpressionTriggered(BreakpointId id,
 {
     return id
         ? tr("Data breakpoint %1 (%2) at %3 triggered.")
-            .arg(id).arg(number).arg(expr)
+            .arg(id.toString()).arg(number).arg(expr)
         : tr("Internal data breakpoint %1 at %2 triggered.")
             .arg(number).arg(expr);
 }
@@ -1507,7 +1507,7 @@ QString DebuggerEngine::msgWatchpointByExpressionTriggered(BreakpointId id,
 {
     return id
         ? tr("Data breakpoint %1 (%2) at %3 in thread %4 triggered.")
-            .arg(id).arg(number).arg(expr).arg(threadId)
+            .arg(id.toString()).arg(number).arg(expr).arg(threadId)
         : tr("Internal data breakpoint %1 at %2 in thread %4 triggered.")
             .arg(number).arg(expr).arg(threadId);
 }
@@ -1517,7 +1517,7 @@ QString DebuggerEngine::msgWatchpointByAddressTriggered(BreakpointId id,
 {
     return id
         ? tr("Data breakpoint %1 (%2) at 0x%3 triggered.")
-            .arg(id).arg(number).arg(address, 0, 16)
+            .arg(id.toString()).arg(number).arg(address, 0, 16)
         : tr("Internal data breakpoint %1 at 0x%2 triggered.")
             .arg(number).arg(address, 0, 16);
 }
@@ -1527,9 +1527,9 @@ QString DebuggerEngine::msgWatchpointByAddressTriggered(BreakpointId id,
 {
     return id
         ? tr("Data breakpoint %1 (%2) at 0x%3 in thread %4 triggered.")
-            .arg(id).arg(number).arg(address, 0, 16).arg(threadId)
+            .arg(id.toString()).arg(number).arg(address, 0, 16).arg(threadId)
         : tr("Internal data breakpoint %1 at 0x%2 in thread %3 triggered.")
-            .arg(id).arg(number).arg(address, 0, 16).arg(threadId);
+            .arg(id.toString()).arg(number).arg(address, 0, 16).arg(threadId);
 }
 
 QString DebuggerEngine::msgBreakpointTriggered(BreakpointId id,
@@ -1537,7 +1537,7 @@ QString DebuggerEngine::msgBreakpointTriggered(BreakpointId id,
 {
     return id
         ? tr("Stopped at breakpoint %1 (%2) in thread %3.")
-            .arg(id).arg(number).arg(threadId)
+            .arg(id.toString()).arg(number).arg(threadId)
         : tr("Stopped at internal breakpoint %1 in thread %2.")
             .arg(number).arg(threadId);
 }
index 6347c19..000e4fd 100644 (file)
@@ -608,21 +608,24 @@ public slots:
     {
         const QAction *act = qobject_cast<QAction *>(sender());
         QTC_ASSERT(act, return);
-        m_breakHandler->removeBreakpoint(act->data().toInt());
+        BreakpointId id = act->data().value<BreakpointId>();
+        m_breakHandler->removeBreakpoint(id);
      }
 
     void breakpointEnableMarginActionTriggered()
     {
         const QAction *act = qobject_cast<QAction *>(sender());
         QTC_ASSERT(act, return);
-        breakHandler()->setEnabled(act->data().toInt(), true);
+        BreakpointId id = act->data().value<BreakpointId>();
+        breakHandler()->setEnabled(id, true);
     }
 
     void breakpointDisableMarginActionTriggered()
     {
         const QAction *act = qobject_cast<QAction *>(sender());
         QTC_ASSERT(act, return);
-        breakHandler()->setEnabled(act->data().toInt(), false);
+        BreakpointId id = act->data().value<BreakpointId>();;
+        breakHandler()->setEnabled(id, false);
     }
 
     void updateWatchersHeader(int section, int, int newSize)
@@ -869,7 +872,7 @@ public slots:
     {
         const QAction *act = qobject_cast<QAction *>(sender());
         QTC_ASSERT(act, return);
-        const BreakpointId id = act->data().toInt();
+        const BreakpointId id = act->data().value<BreakpointId>();
         QTC_ASSERT(id > 0, return);
         BreakWindow::editBreakpoint(id, mainWindow());
     }
@@ -1660,21 +1663,21 @@ void DebuggerPluginPrivate::requestContextMenu(ITextEditor *editor,
     if (id) {
         // Remove existing breakpoint.
         QAction *act = new QAction(menu);
-        act->setData(int(id));
-        act->setText(tr("Remove Breakpoint %1").arg(id));
+        act->setData(QVariant::fromValue(id));
+        act->setText(tr("Remove Breakpoint %1").arg(id.toString()));
         connect(act, SIGNAL(triggered()),
             SLOT(breakpointRemoveMarginActionTriggered()));
         menu->addAction(act);
 
         // Enable/disable existing breakpoint.
         act = new QAction(menu);
-        act->setData(int(id));
+        act->setData(QVariant::fromValue(id));
         if (breakHandler()->isEnabled(id)) {
-            act->setText(tr("Disable Breakpoint %1").arg(id));
+            act->setText(tr("Disable Breakpoint %1").arg(id.toString()));
             connect(act, SIGNAL(triggered()),
                 SLOT(breakpointDisableMarginActionTriggered()));
         } else {
-            act->setText(tr("Enable Breakpoint %1").arg(id));
+            act->setText(tr("Enable Breakpoint %1").arg(id.toString()));
             connect(act, SIGNAL(triggered()),
                 SLOT(breakpointEnableMarginActionTriggered()));
         }
@@ -1682,9 +1685,9 @@ void DebuggerPluginPrivate::requestContextMenu(ITextEditor *editor,
 
         // Edit existing breakpoint.
         act = new QAction(menu);
-        act->setText(tr("Edit Breakpoint %1...").arg(id));
+        act->setText(tr("Edit Breakpoint %1...").arg(id.toString()));
         connect(act, SIGNAL(triggered()), SLOT(slotEditBreakpoint()));
-        act->setData(int(id));
+        act->setData(QVariant::fromValue(id));
         menu->addAction(act);
     } else {
         // Handle non-existing breakpoint.
index 221fd66..2554124 100644 (file)
@@ -465,23 +465,58 @@ void GdbEngine::handleResponse(const QByteArray &buff)
                 // line="1584",shlib="/../libFoo_debug.dylib",times="0"}
                 const GdbMi bkpt = result.findChild("bkpt");
                 const int number = bkpt.findChild("number").data().toInt();
-                if (!isQmlStepBreakpoint1(number) && isQmlStepBreakpoint2(number)) {
-                    BreakpointId id = breakHandler()->findBreakpointByNumber(number);
-                    updateBreakpointDataFromOutput(id, bkpt);
+                if (!isQmlStepBreakpoint(number)) {
+                    BreakHandler *handler = breakHandler();
+                    BreakpointId id = handler->findBreakpointByNumber(number);
+                    BreakpointResponse br = handler->response(id);
+                    updateResponse(br, bkpt);
+                    handler->setResponse(id, br);
                     attemptAdjustBreakpointLocation(id);
                 }
             } else if (asyncClass == "breakpoint-modified") {
                 // New in FSF gdb since 2011-04-27.
-                // "{bkpt={number="2",type="breakpoint",disp="keep",enabled="y",
-                // addr="0x014e0e34",func="Myns::qFatal(char const*, ...)",
-                // file="global/qglobal.cpp",fullname="/data/dev/...cpp",
-                // line="2534",times="0",script={"return"},
-                // original-location="'Myns::qFatal'"}}"
-                const GdbMi bkpt = result.findChild("bkpt");
-                const int number = bkpt.findChild("number").data().toInt();
-                if (!isQmlStepBreakpoint1(number) && isQmlStepBreakpoint2(number)) {
-                    BreakpointId id = breakHandler()->findBreakpointByNumber(number);
-                    updateBreakpointDataFromOutput(id, bkpt);
+                // "{bkpt={number="3",type="breakpoint",disp="keep",
+                // enabled="y",addr="<MULTIPLE>",times="1",
+                // original-location="\\",simple_gdbtest_app.cpp\\":135"},
+                // {number="3.1",enabled="y",addr="0x0805ff68",
+                // func="Vector<int>::Vector(int)",
+                // file="simple_gdbtest_app.cpp",
+                // fullname="/data/...line="135"},{number="3.2"...}}"
+
+                // Note the leading comma in original-location. Filter it out.
+                // We don't need the field anyway.
+                QByteArray ba = result.toString();
+                ba = '[' + ba.mid(6, ba.size() - 7) + ']';
+                const int pos1 = ba.indexOf(",original-location");
+                const int pos2 = ba.indexOf("\":", pos1 + 2);
+                const int pos3 = ba.indexOf('"', pos2 + 2);
+                ba.replace(pos1, pos3 - pos1 + 1, "");
+                result = GdbMi();
+                result.fromString(ba);
+                BreakHandler *handler = breakHandler();
+                BreakpointId id = BreakpointId(-1);
+                BreakpointResponse br;
+                foreach (const GdbMi &bkpt, result.children()) {
+                    const QByteArray nr = bkpt.findChild("number").data();
+                    if (nr.contains(".")) {
+                        // A sub-breakpoint.
+                        int subNumber = nr.mid(nr.indexOf('.') + 1).toInt();
+                        BreakpointResponse sub;
+                        updateResponse(sub, bkpt);
+                        sub.number = br.number;
+                        sub.type = br.type;
+                        sub.subNumber = subNumber;
+                        sub.extra.clear();
+                        handler->appendSubBreakpoint(id, sub);
+                    } else {
+                        // A primary breakpoint.
+                        id = handler->findBreakpointByNumber(nr.toInt());
+                        br = handler->response(id);
+                        updateResponse(br, bkpt);
+                    }
+                }
+                if (!isQmlStepBreakpoint(br.number)) {
+                    handler->setResponse(id, br);
                     attemptAdjustBreakpointLocation(id);
                 }
                 m_hasBreakpointNotifications = true;
@@ -666,7 +701,8 @@ void GdbEngine::readGdbStandardOutput()
 
 void GdbEngine::interruptInferior()
 {
-    QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state(); return);
+    QTC_ASSERT(state() == InferiorStopRequested,
+        qDebug() << "INTERRUPT INFERIOR: " << state(); return);
 
     if (debuggerCore()->boolSetting(TargetAsync)) {
         postCommand("-exec-interrupt");
@@ -1252,8 +1288,7 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
         fullName = QString::fromUtf8(frame.findChild("file").data());
 
     if (bkptno && frame.isValid()
-            && !isQmlStepBreakpoint1(bkptno)
-            && !isQmlStepBreakpoint2(bkptno)
+            && !isQmlStepBreakpoint(bkptno)
             && !isQFatalBreakpoint(bkptno)) {
         // Use opportunity to update the breakpoint marker position.
         BreakHandler *handler = breakHandler();
@@ -1275,8 +1310,7 @@ void GdbEngine::handleStopResponse(const GdbMi &data)
     // Quickly set the location marker.
     if (lineNumber && !debuggerCore()->boolSetting(OperateByInstruction)
             && QFileInfo(fullName).exists()
-            && !isQmlStepBreakpoint1(bkptno)
-            && !isQmlStepBreakpoint2(bkptno)
+            && !isQmlStepBreakpoint(bkptno)
             && !isQFatalBreakpoint(bkptno))
         gotoLocation(Location(fullName, lineNumber));
 
@@ -1663,6 +1697,11 @@ void GdbEngine::handleShowVersion(const GdbResponse &response)
     }
 }
 
+void GdbEngine::handleListFeatures(const GdbResponse &response)
+{
+    showMessage(_("FEATURES: " + response.toString()));
+}
+
 void GdbEngine::handleHasPython(const GdbResponse &response)
 {
     if (response.resultClass == GdbResultDone) {
@@ -2241,12 +2280,10 @@ void GdbEngine::setTokenBarrier()
 //
 //////////////////////////////////////////////////////////////////////
 
-void GdbEngine::updateBreakpointDataFromOutput(BreakpointId id, const GdbMi &bkpt)
+void GdbEngine::updateResponse(BreakpointResponse &response, const GdbMi &bkpt)
 {
     QTC_ASSERT(bkpt.isValid(), return);
 
-    BreakpointResponse response = breakHandler()->response(id);
-
     response.multiple = false;
     response.enabled = true;
     response.pending = false;
@@ -2322,8 +2359,6 @@ void GdbEngine::updateBreakpointDataFromOutput(BreakpointId id, const GdbMi &bkp
     }
     if (!name.isEmpty())
         response.fileName = name;
-
-    breakHandler()->setResponse(id, response);
 }
 
 QString GdbEngine::breakLocation(const QString &file) const
@@ -2374,21 +2409,21 @@ QByteArray GdbEngine::breakpointLocation2(BreakpointId id)
 
 void GdbEngine::handleWatchInsert(const GdbResponse &response)
 {
-    const int id = response.cookie.toInt();
+    BreakpointId id = response.cookie.value<BreakpointId>();
     if (response.resultClass == GdbResultDone) {
         BreakHandler *handler = breakHandler();
-        BreakpointResponse bresponse = handler->response(id);
+        BreakpointResponse br = handler->response(id);
         // "Hardware watchpoint 2: *0xbfffed40\n"
         QByteArray ba = response.data.findChild("consolestreamoutput").data();
         GdbMi wpt = response.data.findChild("wpt");
         if (wpt.isValid()) {
             // Mac yields:
             //>32^done,wpt={number="4",exp="*4355182176"}
-            bresponse.number = wpt.findChild("number").data().toInt();
+            br.number = wpt.findChild("number").data().toInt();
             QByteArray exp = wpt.findChild("exp").data();
             if (exp.startsWith('*'))
-                bresponse.address = exp.mid(1).toULongLong(0, 0);
-            handler->setResponse(id, bresponse);
+                br.address = exp.mid(1).toULongLong(0, 0);
+            handler->setResponse(id, br);
             QTC_ASSERT(!handler->needsChange(id), /**/);
             handler->notifyBreakpointInsertOk(id);
         } else if (ba.startsWith("Hardware watchpoint ")
@@ -2397,10 +2432,10 @@ void GdbEngine::handleWatchInsert(const GdbResponse &response)
             const int end = ba.indexOf(':');
             const int begin = ba.lastIndexOf(' ', end) + 1;
             const QByteArray address = ba.mid(end + 2).trimmed();
-            bresponse.number = ba.mid(begin, end - begin).toInt();
+            br.number = ba.mid(begin, end - begin).toInt();
             if (address.startsWith('*'))
-                bresponse.address = address.mid(1).toULongLong(0, 0);
-            handler->setResponse(id, bresponse);
+                br.address = address.mid(1).toULongLong(0, 0);
+            handler->setResponse(id, br);
             QTC_ASSERT(!handler->needsChange(id), /**/);
             handler->notifyBreakpointInsertOk(id);
         } else {
@@ -2423,13 +2458,13 @@ void GdbEngine::attemptAdjustBreakpointLocation(BreakpointId id)
     breakHandler()->setResponse(id, response);
     postCommand("info line *0x" + QByteArray::number(response.address, 16),
         NeedsStop | RebuildBreakpointModel,
-        CB(handleInfoLine), id);
+        CB(handleInfoLine), QVariant::fromValue(id));
 }
 
 void GdbEngine::handleCatchInsert(const GdbResponse &response)
 {
     BreakHandler *handler = breakHandler();
-    BreakpointId id(response.cookie.toInt());
+    BreakpointId id = response.cookie.value<BreakpointId>();
     if (response.resultClass == GdbResultDone) {
         handler->notifyBreakpointInsertOk(id);
         attemptAdjustBreakpointLocation(id);
@@ -2439,21 +2474,23 @@ void GdbEngine::handleCatchInsert(const GdbResponse &response)
 void GdbEngine::handleBreakInsert1(const GdbResponse &response)
 {
     BreakHandler *handler = breakHandler();
-    BreakpointId id(response.cookie.toInt());
+    BreakpointId id = response.cookie.value<BreakpointId>();
     if (response.resultClass == GdbResultDone) {
         // Interesting only on Mac?
         GdbMi bkpt = response.data.findChild("bkpt");
-        updateBreakpointDataFromOutput(id, bkpt);
+        BreakpointResponse br = handler->response(id);
+        updateResponse(br, bkpt);
+        handler->setResponse(id, br);
         if (handler->needsChange(id)) {
             handler->notifyBreakpointChangeAfterInsertNeeded(id);
             changeBreakpoint(id);
         } else {
             handler->notifyBreakpointInsertOk(id);
         }
-        BreakpointResponse bresponse = handler->response(id);
+        br = handler->response(id);
         attemptAdjustBreakpointLocation(id);
-        if (bresponse.multiple && bresponse.addresses.isEmpty())
-            postCommand("info break " + QByteArray::number(bresponse.number),
+        if (br.multiple && br.addresses.isEmpty())
+            postCommand("info break " + QByteArray::number(br.number),
                 NeedsStop, CB(handleBreakListMultiple), QVariant(id));
     } else if (response.data.findChild("msg").data().contains("Unknown option")) {
         // Older version of gdb don't know the -a option to set tracepoints
@@ -2463,22 +2500,24 @@ void GdbEngine::handleBreakInsert1(const GdbResponse &response)
         QByteArray cmd = "trace "
             "\"" + GdbMi::escapeCString(fileName).toLocal8Bit() + "\":"
             + QByteArray::number(lineNumber);
+        QVariant vid = QVariant::fromValue(id);
         postCommand(cmd, NeedsStop | RebuildBreakpointModel,
-            CB(handleTraceInsert2), id);
+            CB(handleTraceInsert2), vid);
     } else {
         // Some versions of gdb like "GNU gdb (GDB) SUSE (6.8.91.20090930-2.4)"
         // know how to do pending breakpoints using CLI but not MI. So try
         // again with MI.
         QByteArray cmd = "break " + breakpointLocation2(id);
+        QVariant vid = QVariant::fromValue(id);
         postCommand(cmd, NeedsStop | RebuildBreakpointModel,
-            CB(handleBreakInsert2), id);
+            CB(handleBreakInsert2), vid);
     }
 }
 
 void GdbEngine::handleBreakInsert2(const GdbResponse &response)
 {
     if (response.resultClass == GdbResultDone) {
-        BreakpointId id(response.cookie.toInt());
+        BreakpointId id = response.cookie.value<BreakpointId>();
         attemptAdjustBreakpointLocation(id);
         breakHandler()->notifyBreakpointInsertOk(id);
     } else {
@@ -2541,6 +2580,7 @@ void GdbEngine::handleBreakList(const GdbMi &table)
         }
     }
 
+    BreakHandler *handler = breakHandler();
     foreach (const GdbMi &bkpt, bkpts) {
         BreakpointResponse needle;
         needle.number = bkpt.findChild("number").data().toInt();
@@ -2548,14 +2588,17 @@ void GdbEngine::handleBreakList(const GdbMi &table)
             continue;
         if (isQFatalBreakpoint(needle.number))
             continue;
-        BreakpointId id = breakHandler()->findSimilarBreakpoint(needle);
-        if (id != BreakpointId(-1)) {
-            updateBreakpointDataFromOutput(id, bkpt);
+        BreakpointId id = handler->findSimilarBreakpoint(needle);
+        if (id.isValid()) {
+            BreakpointResponse response = handler->response(id);
+            updateResponse(response, bkpt);
+            handler->setResponse(id, response);
             attemptAdjustBreakpointLocation(id);
-            BreakpointResponse response = breakHandler()->response(id);
+            response = handler->response(id);
             if (response.multiple && response.addresses.isEmpty())
                 postCommand("info break " + QByteArray::number(response.number),
-                    NeedsStop, CB(handleBreakListMultiple), QVariant(id));
+                    NeedsStop, CB(handleBreakListMultiple),
+                    QVariant::fromValue(id));
         } else {
             qDebug() << "  NOTHING SUITABLE FOUND";
             showMessage(_("CANNOT FIND BP: " + bkpt.toString()));
@@ -2568,7 +2611,7 @@ void GdbEngine::handleBreakList(const GdbMi &table)
 void GdbEngine::handleBreakListMultiple(const GdbResponse &response)
 {
     QTC_ASSERT(response.resultClass == GdbResultDone, /**/)
-    const BreakpointId id = response.cookie.toInt();
+    const BreakpointId id = response.cookie.value<BreakpointId>();
     const QString str = QString::fromLocal8Bit(
         response.data.findChild("consolestreamoutput").data());
     extractDataFromInfoBreak(str, id);
@@ -2577,7 +2620,7 @@ void GdbEngine::handleBreakListMultiple(const GdbResponse &response)
 void GdbEngine::handleBreakDisable(const GdbResponse &response)
 {
     QTC_ASSERT(response.resultClass == GdbResultDone, /**/)
-    const BreakpointId id = response.cookie.toInt();
+    const BreakpointId id = response.cookie.value<BreakpointId>();
     BreakHandler *handler = breakHandler();
     // This should only be the requested state.
     QTC_ASSERT(!handler->isEnabled(id), /* Prevent later recursion */);
@@ -2590,7 +2633,7 @@ void GdbEngine::handleBreakDisable(const GdbResponse &response)
 void GdbEngine::handleBreakEnable(const GdbResponse &response)
 {
     QTC_ASSERT(response.resultClass == GdbResultDone, /**/)
-    const BreakpointId id = response.cookie.toInt();
+    const BreakpointId id = response.cookie.value<BreakpointId>();
     BreakHandler *handler = breakHandler();
     // This should only be the requested state.
     QTC_ASSERT(handler->isEnabled(id), /* Prevent later recursion */);
@@ -2603,7 +2646,7 @@ void GdbEngine::handleBreakEnable(const GdbResponse &response)
 void GdbEngine::handleBreakThreadSpec(const GdbResponse &response)
 {
     QTC_ASSERT(response.resultClass == GdbResultDone, /**/)
-    const BreakpointId id = response.cookie.toInt();
+    const BreakpointId id = response.cookie.value<BreakpointId>();
     BreakHandler *handler = breakHandler();
     BreakpointResponse br = handler->response(id);
     br.threadSpec = handler->threadSpec(id);
@@ -2626,7 +2669,7 @@ void GdbEngine::handleBreakIgnore(const GdbResponse &response)
     // gdb 6.3 does not produce any console output
     QTC_ASSERT(response.resultClass == GdbResultDone, /**/)
     QString msg = _(response.data.findChild("consolestreamoutput").data());
-    BreakpointId id = response.cookie.toInt();
+    BreakpointId id = response.cookie.value<BreakpointId>();
     BreakHandler *handler = breakHandler();
     BreakpointResponse br = handler->response(id);
     //if (msg.contains(__("Will stop next time breakpoint")))
@@ -2645,7 +2688,7 @@ void GdbEngine::handleBreakCondition(const GdbResponse &response)
 {
     // Can happen at invalid condition strings.
     //QTC_ASSERT(response.resultClass == GdbResultDone, /**/)
-    const BreakpointId id = response.cookie.toInt();
+    const BreakpointId id = response.cookie.value<BreakpointId>();
     BreakHandler *handler = breakHandler();
     // We just assume it was successful. Otherwise we had to parse
     // the output stream data.
@@ -2723,7 +2766,7 @@ void GdbEngine::handleInfoLine(const GdbResponse &response)
         // at address 0x80526aa <_Z10...+131> and ends at 0x80526b5
         // <_Z10testQStackv+142>.\n"
         QByteArray ba = response.data.findChild("consolestreamoutput").data();
-        const BreakpointId id = response.cookie.toInt();
+        const BreakpointId id = response.cookie.value<BreakpointId>();
         const int pos = ba.indexOf(' ', 5);
         if (ba.startsWith("Line ") && pos != -1) {
             const int line = ba.mid(5, pos - 5).toInt();
@@ -2763,38 +2806,39 @@ void GdbEngine::insertBreakpoint(BreakpointId id)
     QTC_ASSERT(handler->state(id) == BreakpointInsertRequested, /**/);
     handler->notifyBreakpointInsertProceeding(id);
     BreakpointType type = handler->type(id);
+    QVariant vid = QVariant::fromValue(id);
     if (type == WatchpointAtAddress) {
         postCommand("watch " + addressSpec(handler->address(id)),
             NeedsStop | RebuildBreakpointModel,
-            CB(handleWatchInsert), id);
+            CB(handleWatchInsert), vid);
         return;
     }
     if (type == WatchpointAtExpression) {
         postCommand("watch " + handler->expression(id).toLocal8Bit(),
             NeedsStop | RebuildBreakpointModel,
-            CB(handleWatchInsert), id);
+            CB(handleWatchInsert), vid);
         return;
     }
     if (type == BreakpointAtFork) {
         postCommand("catch fork", NeedsStop | RebuildBreakpointModel,
-            CB(handleCatchInsert), id);
+            CB(handleCatchInsert), vid);
         postCommand("catch vfork", NeedsStop | RebuildBreakpointModel,
-            CB(handleCatchInsert), id);
+            CB(handleCatchInsert), vid);
         return;
     }
     //if (type == BreakpointAtVFork) {
     //    postCommand("catch vfork", NeedsStop | RebuildBreakpointModel,
-    //        CB(handleCatchInsert), id);
+    //        CB(handleCatchInsert), vid);
     //    return;
     //}
     if (type == BreakpointAtExec) {
         postCommand("catch exec", NeedsStop | RebuildBreakpointModel,
-            CB(handleCatchInsert), id);
+            CB(handleCatchInsert), vid);
         return;
     }
     if (type == BreakpointAtSysCall) {
         postCommand("catch syscall", NeedsStop | RebuildBreakpointModel,
-            CB(handleCatchInsert), id);
+            CB(handleCatchInsert), vid);
         return;
     }
 
@@ -2821,7 +2865,7 @@ void GdbEngine::insertBreakpoint(BreakpointId id)
     //    cmd += "-c " + data->condition + ' ';
     cmd += breakpointLocation(id);
     postCommand(cmd, NeedsStop | RebuildBreakpointModel,
-        CB(handleBreakInsert1), id);
+        CB(handleBreakInsert1), vid);
 }
 
 void GdbEngine::changeBreakpoint(BreakpointId id)
@@ -2838,12 +2882,13 @@ void GdbEngine::changeBreakpoint(BreakpointId id)
         handler->notifyBreakpointChangeProceeding(id);
     const BreakpointState state2 = handler->state(id);
     QTC_ASSERT(state2 == BreakpointChangeProceeding, qDebug() << state2);
+    QVariant vid = QVariant::fromValue(id);
 
     if (data.threadSpec != response.threadSpec) {
         // The only way to change this seems to be to re-set the bp completely.
         postCommand("-break-delete " + bpnr,
             NeedsStop | RebuildBreakpointModel,
-            CB(handleBreakThreadSpec), id);
+            CB(handleBreakThreadSpec), vid);
         return;
     }
     if (data.command != response.command) {
@@ -2856,31 +2901,31 @@ void GdbEngine::changeBreakpoint(BreakpointId id)
             }
         }
         postCommand(breakCommand, NeedsStop | RebuildBreakpointModel,
-                    CB(handleBreakIgnore), id);
+                    CB(handleBreakIgnore), vid);
         return;
     }
     if (!data.conditionsMatch(response.condition)) {
         postCommand("condition " + bpnr + ' '  + data.condition,
             NeedsStop | RebuildBreakpointModel,
-            CB(handleBreakCondition), id);
+            CB(handleBreakCondition), vid);
         return;
     }
     if (data.ignoreCount != response.ignoreCount) {
         postCommand("ignore " + bpnr + ' ' + QByteArray::number(data.ignoreCount),
             NeedsStop | RebuildBreakpointModel,
-            CB(handleBreakIgnore), id);
+            CB(handleBreakIgnore), vid);
         return;
     }
     if (!data.enabled && response.enabled) {
         postCommand("-break-disable " + bpnr,
             NeedsStop | RebuildBreakpointModel,
-            CB(handleBreakDisable), id);
+            CB(handleBreakDisable), vid);
         return;
     }
     if (data.enabled && !response.enabled) {
         postCommand("-break-enable " + bpnr,
             NeedsStop | RebuildBreakpointModel,
-            CB(handleBreakEnable), id);
+            CB(handleBreakEnable), vid);
         return;
     }
     handler->notifyBreakpointChangeOk(id);
@@ -4475,6 +4520,7 @@ bool GdbEngine::startGdb(const QStringList &args, const QString &settingsIdHint)
 
     showMessage(_("GDB STARTED, INITIALIZING IT"));
     postCommand("show version", CB(handleShowVersion));
+    postCommand("-list-features", CB(handleListFeatures));
 
     //postCommand("-enable-timings");
     //postCommand("set print static-members off"); // Seemingly doesn't work.
@@ -4895,6 +4941,11 @@ void GdbEngine::handleSetQmlStepBreakpoint(const GdbResponse &response)
     masterEngine()->readyToExecuteQmlStep();
 }
 
+bool GdbEngine::isQmlStepBreakpoint(int bpnr) const
+{
+    return isQmlStepBreakpoint1(bpnr) || isQmlStepBreakpoint2(bpnr);
+}
+
 bool GdbEngine::isQmlStepBreakpoint1(int bpnr) const
 {
     //qDebug() << "CHECK 1: " << m_qmlBreakpointNumbers[1] << bpnr;
index d4aa4c0..0201b99 100644 (file)
@@ -435,6 +435,7 @@ private: ////////// Gdb Output, State & Capability Handling //////////
 
     // Gdb initialization sequence
     void handleShowVersion(const GdbResponse &response);
+    void handleListFeatures(const GdbResponse &response);
     void handleHasPython(const GdbResponse &response);
 
     int m_gdbVersion; // 6.8.0 is 60800
@@ -506,7 +507,7 @@ private: ////////// View & Data Stuff //////////
     void handleCatchInsert(const GdbResponse &response);
     void handleInfoLine(const GdbResponse &response);
     void extractDataFromInfoBreak(const QString &output, BreakpointId);
-    void updateBreakpointDataFromOutput(BreakpointId id, const GdbMi &bkpt);
+    void updateResponse(BreakpointResponse &response, const GdbMi &bkpt);
     QByteArray breakpointLocation(BreakpointId id); // For gdb/MI.
     QByteArray breakpointLocation2(BreakpointId id); // For gdb/CLI fallback.
     QString breakLocation(const QString &file) const;
@@ -721,6 +722,7 @@ private: ////////// View & Data Stuff //////////
     bool m_preparedForQmlBreak;
     bool setupQmlStep(bool on);
     void handleSetQmlStepBreakpoint(const GdbResponse &response);
+    bool isQmlStepBreakpoint(int bpnr) const;
     bool isQmlStepBreakpoint1(int bpnr) const;
     bool isQmlStepBreakpoint2(int bpnr) const;
     bool isQFatalBreakpoint(int bpnr) const;
index e7a50f3..5e35d25 100644 (file)
@@ -506,8 +506,9 @@ void IPCEngineHost::rpcCallback(quint64 f, QByteArray payload)
                 attemptBreakpointSynchronization();
                 QDataStream s(payload);
                 SET_NATIVE_BYTE_ORDER(s);
-                BreakpointId id;
-                s >> id;
+                quint64 d;
+                s >> d;
+                BreakpointId id = BreakpointId::fromInternalId(d);
                 breakHandler()->notifyBreakpointInsertOk(id);
             }
             break;
@@ -515,8 +516,9 @@ void IPCEngineHost::rpcCallback(quint64 f, QByteArray payload)
             {
                 QDataStream s(payload);
                 SET_NATIVE_BYTE_ORDER(s);
-                BreakpointId id;
-                s >> id;
+                quint64 d;
+                s >> d;
+                BreakpointId id = BreakpointId::fromInternalId(d);
                 breakHandler()->notifyBreakpointInsertFailed(id);
             }
             break;
@@ -524,8 +526,9 @@ void IPCEngineHost::rpcCallback(quint64 f, QByteArray payload)
             {
                 QDataStream s(payload);
                 SET_NATIVE_BYTE_ORDER(s);
-                BreakpointId id;
-                s >> id;
+                quint64 d;
+                s >> d;
+                BreakpointId id = BreakpointId::fromInternalId(d);
                 breakHandler()->notifyBreakpointRemoveOk(id);
             }
             break;
@@ -533,8 +536,9 @@ void IPCEngineHost::rpcCallback(quint64 f, QByteArray payload)
             {
                 QDataStream s(payload);
                 SET_NATIVE_BYTE_ORDER(s);
-                BreakpointId id;
-                s >> id;
+                quint64 d;
+                s >> d;
+                BreakpointId id = BreakpointId::fromInternalId(d);
                 breakHandler()->notifyBreakpointRemoveFailed(id);
             }
             break;
@@ -542,8 +546,9 @@ void IPCEngineHost::rpcCallback(quint64 f, QByteArray payload)
             {
                 QDataStream s(payload);
                 SET_NATIVE_BYTE_ORDER(s);
-                BreakpointId id;
-                s >> id;
+                quint64 d;
+                s >> d;
+                BreakpointId id = BreakpointId::fromInternalId(d);
                 breakHandler()->notifyBreakpointChangeOk(id);
             }
             break;
@@ -551,8 +556,9 @@ void IPCEngineHost::rpcCallback(quint64 f, QByteArray payload)
             {
                 QDataStream s(payload);
                 SET_NATIVE_BYTE_ORDER(s);
-                BreakpointId id;
-                s >> id;
+                quint64 d;
+                s >> d;
+                BreakpointId id = BreakpointId::fromInternalId(d);
                 breakHandler()->notifyBreakpointChangeFailed(id);
             }
             break;
@@ -560,9 +566,10 @@ void IPCEngineHost::rpcCallback(quint64 f, QByteArray payload)
             {
                 QDataStream s(payload);
                 SET_NATIVE_BYTE_ORDER(s);
-                BreakpointId id;
+                quint64 dd;
                 BreakpointParameters d;
-                s >> id >> d;
+                s >> dd >> d;
+                BreakpointId id = BreakpointId::fromInternalId(dd);
                 breakHandler()->notifyBreakpointAdjusted(id, d);
             }
             break;
index 6f5eb09..f23aad8 100644 (file)
@@ -39,7 +39,7 @@
 #include "debuggerengine.h"
 #include "watchutils.h"
 
-#if USE_MODEL_TEST
+#if USE_WATCH_MODEL_TEST
 #include "modeltest.h"
 #endif
 
@@ -216,8 +216,8 @@ void WatchModel::removeOutdated()
     foreach (WatchItem *child, m_root->children)
         removeOutdatedHelper(child);
 #if DEBUG_MODEL
-#if USE_MODEL_TEST
-    //(void) new ModelTest(this, this);
+#if USE_WATCH_MODEL_TEST
+    (void) new ModelTest(this, this);
 #endif
 #endif
 }