From 9e5bcf2f4bfcfd4335f7478865dea66822cd2277 Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <Friedemann.Kleint@nokia.com>
Date: Thu, 30 Jun 2011 11:01:10 +0200
Subject: [PATCH] Debugger [CDB]: Fix module resolution.

Use breakpoint id as response id to identify breakpoints
in reponse to 'list breakpoint' command.

Change-Id: I31686aef0193bf2e26e38482c7efebf294a358c4
Reviewed-on: http://codereview.qt.nokia.com/940
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: hjk <qthjk@ovi.com>
---
 src/plugins/debugger/breakpoint.cpp          |  7 +++++++
 src/plugins/debugger/cdb/cdbengine.cpp       | 14 +++++++-------
 src/plugins/debugger/cdb/cdbparsehelpers.cpp | 14 +++++---------
 src/plugins/debugger/cdb/cdbparsehelpers.h   |  2 +-
 4 files changed, 20 insertions(+), 17 deletions(-)

diff --git a/src/plugins/debugger/breakpoint.cpp b/src/plugins/debugger/breakpoint.cpp
index c409dde18fa..4c0983d1ddf 100644
--- a/src/plugins/debugger/breakpoint.cpp
+++ b/src/plugins/debugger/breakpoint.cpp
@@ -51,6 +51,9 @@ namespace Internal {
 
     This identifies a breakpoint in the \c BreakHandler. The
     major parts are strictly increasing over time.
+
+    The minor part identifies a multiple breakpoint
+    set for example by gdb in constructors.
 */
 
 
@@ -105,6 +108,10 @@ BreakpointModelId BreakpointModelId::child(int row) const
 
     This is what the external debuggers use to identify a breakpoint.
     It is only valid for one debugger run.
+
+    In gdb, the breakpoint number is used, which is constant
+    during a session. CDB's breakpoint numbers vary if breakpoints
+    are deleted, so, the ID is used.
 */
 
 BreakpointResponseId::BreakpointResponseId(const QByteArray &ba)
diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp
index a2ea611039d..e8b464d5370 100644
--- a/src/plugins/debugger/cdb/cdbengine.cpp
+++ b/src/plugins/debugger/cdb/cdbengine.cpp
@@ -2512,6 +2512,7 @@ void CdbEngine::attemptBreakpointSynchronization()
         BreakpointParameters parameters = handler->breakpointData(id);
         BreakpointResponse response;
         response.fromParameters(parameters);
+        response.id = BreakpointResponseId(id.majorPart(), id.minorPart());
         // If we encountered that file and have a module for it: Add it.
         if (parameters.type == BreakpointByFileAndLine && parameters.module.isEmpty()) {
             const QHash<QString, QString>::const_iterator it = m_fileNameModuleHash.constFind(parameters.fileName);
@@ -2833,14 +2834,14 @@ void CdbEngine::handleBreakPoints(const GdbMi &value)
     BreakHandler *handler = breakHandler();
     foreach (const GdbMi &breakPointG, value.children()) {
         BreakpointResponse reportedResponse;
-        const BreakpointResponseId id = parseBreakPoint(breakPointG, &reportedResponse);
+        parseBreakPoint(breakPointG, &reportedResponse);
         if (debugBreakpoints)
-            qDebug("  Parsed %d: pending=%d %s\n", id.majorPart(),
+            qDebug("  Parsed %d: pending=%d %s\n", reportedResponse.id.majorPart(),
                 reportedResponse.pending,
                 qPrintable(reportedResponse.toString()));
-
-        if (!reportedResponse.pending) {
-            BreakpointModelId mid = handler->findBreakpointByResponseId(id);
+        if (reportedResponse.id.isValid() && !reportedResponse.pending) {
+            const BreakpointModelId mid = handler->findBreakpointByResponseId(reportedResponse.id);
+            QTC_ASSERT(mid.isValid(), continue; )
             const PendingBreakPointMap::iterator it = m_pendingBreakpointMap.find(mid);
             if (it != m_pendingBreakpointMap.end()) {
                 // Complete the response and set on handler.
@@ -2852,9 +2853,8 @@ void CdbEngine::handleBreakPoints(const GdbMi &value)
                 currentResponse.enabled = reportedResponse.enabled;
                 formatCdbBreakPointResponse(mid, currentResponse, str);
                 if (debugBreakpoints)
-                    qDebug("  Setting for %d: %s\n", id.majorPart(),
+                    qDebug("  Setting for %d: %s\n", currentResponse.id.majorPart(),
                         qPrintable(currentResponse.toString()));
-                BreakpointModelId mid = handler->findBreakpointByResponseId(id);
                 handler->setResponse(mid, currentResponse);
                 m_pendingBreakpointMap.erase(it);
             }
diff --git a/src/plugins/debugger/cdb/cdbparsehelpers.cpp b/src/plugins/debugger/cdb/cdbparsehelpers.cpp
index 92cc42090bb..bade3a09a9a 100644
--- a/src/plugins/debugger/cdb/cdbparsehelpers.cpp
+++ b/src/plugins/debugger/cdb/cdbparsehelpers.cpp
@@ -298,21 +298,18 @@ static inline bool gdbmiChildToBool(const GdbMi &parent, const char *childName,
 // Parse extension command listing breakpoints.
 // Note that not all fields are returned, since file, line, function are encoded
 // in the expression (that is in addition deleted on resolving for a bp-type breakpoint).
-BreakpointResponseId parseBreakPoint(const GdbMi &gdbmi, BreakpointResponse *r,
-                             QString *expression /*  = 0 */)
+void parseBreakPoint(const GdbMi &gdbmi, BreakpointResponse *r,
+                     QString *expression /*  = 0 */)
 {
-    BreakpointResponseId id = BreakpointResponseId(-1);
-    int majorPart = 0;
-    gdbmiChildToInt(gdbmi, "number", &majorPart);
     gdbmiChildToBool(gdbmi, "enabled", &(r->enabled));
     gdbmiChildToBool(gdbmi, "deferred", &(r->pending));
-    r->id = BreakpointResponseId(majorPart);
+    r->id = BreakpointResponseId();
     const GdbMi idG = gdbmi.findChild("id");
     if (idG.isValid()) { // Might not be valid if there is not id
         bool ok;
-        const BreakpointResponseId cid(idG.data().toInt(&ok));
+        const int id = idG.data().toInt(&ok);
         if (ok)
-            id = cid;
+            r->id = BreakpointResponseId(id);
     }
     const GdbMi moduleG = gdbmi.findChild("module");
     if (moduleG.isValid())
@@ -328,7 +325,6 @@ BreakpointResponseId parseBreakPoint(const GdbMi &gdbmi, BreakpointResponse *r,
     if (gdbmiChildToInt(gdbmi, "passcount", &(r->ignoreCount)))
         r->ignoreCount--;
     gdbmiChildToInt(gdbmi, "thread", &(r->threadSpec));
-    return id;
 }
 
 QByteArray cdbWriteMemoryCommand(quint64 addr, const QByteArray &data)
diff --git a/src/plugins/debugger/cdb/cdbparsehelpers.h b/src/plugins/debugger/cdb/cdbparsehelpers.h
index 66f453b1d66..15a281a8789 100644
--- a/src/plugins/debugger/cdb/cdbparsehelpers.h
+++ b/src/plugins/debugger/cdb/cdbparsehelpers.h
@@ -69,7 +69,7 @@ QByteArray cdbAddBreakpointCommand(const BreakpointParameters &d,
 // Parse extension command listing breakpoints.
 // Note that not all fields are returned, since file, line, function are encoded
 // in the expression (that is in addition deleted on resolving for a bp-type breakpoint).
-BreakpointResponseId parseBreakPoint(const GdbMi &gdbmi, BreakpointResponse *r, QString *expression = 0);
+void parseBreakPoint(const GdbMi &gdbmi, BreakpointResponse *r, QString *expression = 0);
 
 // Convert a CDB integer value: '00000000`0012a290' -> '12a290', '0n10' ->'10'
 QByteArray fixCdbIntegerValue(QByteArray t, bool stripLeadingZeros = false, int *basePtr = 0);
-- 
GitLab