From e8dafc28a5817e07e90b4d16d4ba68317ca1d7cd Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <Friedemann.Kleint@nokia.com>
Date: Tue, 30 Jun 2009 15:50:56 +0200
Subject: [PATCH] Improve error logging of CDB breakpoint setting.

Output warnings to debugger log. Prevent breakpoints from
being set several times when loading session data by
clearing the complete break handler.
Reviewed-by: hjk <qtc-committer@nokia.com>
---
 src/plugins/debugger/breakhandler.cpp       | 51 ++++++++++++++-------
 src/plugins/debugger/cdb/cdbbreakpoint.cpp  | 38 +++++++++------
 src/plugins/debugger/cdb/cdbbreakpoint.h    |  3 +-
 src/plugins/debugger/cdb/cdbdebugengine.cpp | 11 ++++-
 src/plugins/debugger/cdb/cdbmodules.cpp     |  1 +
 5 files changed, 70 insertions(+), 34 deletions(-)

diff --git a/src/plugins/debugger/breakhandler.cpp b/src/plugins/debugger/breakhandler.cpp
index 10493f47e4a..b903916acff 100644
--- a/src/plugins/debugger/breakhandler.cpp
+++ b/src/plugins/debugger/breakhandler.cpp
@@ -279,8 +279,12 @@ void BreakHandler::removeAt(int index)
 
 void BreakHandler::clear()
 {
-    for (int index = size(); --index >= 0; )
-        removeAt(index);
+    qDeleteAll(m_bp);
+    m_bp.clear();
+    m_enabled.clear();
+    m_disabled.clear();
+    m_removed.clear();
+    m_inserted.clear();
 }
 
 int BreakHandler::findBreakpoint(const BreakpointData &needle)
@@ -326,19 +330,19 @@ void BreakHandler::saveBreakpoints()
         const BreakpointData *data = at(index);
         QMap<QString, QVariant> map;
         if (!data->fileName.isEmpty())
-            map["filename"] = data->fileName;
+            map.insert(QLatin1String("filename"), data->fileName);
         if (!data->lineNumber.isEmpty())
-            map["linenumber"] = data->lineNumber;
+            map.insert(QLatin1String("linenumber"), data->lineNumber);
         if (!data->funcName.isEmpty())
-            map["funcname"] = data->funcName;
+            map.insert(QLatin1String("funcname"), data->funcName);
         if (!data->condition.isEmpty())
-            map["condition"] = data->condition;
+            map.insert(QLatin1String("condition"), data->condition);
         if (!data->ignoreCount.isEmpty())
-            map["ignorecount"] = data->ignoreCount;
+            map.insert(QLatin1String("ignorecount"), data->ignoreCount);
         if (!data->enabled)
-            map["disabled"] = "1";
+            map.insert(QLatin1String("disabled"), QLatin1String("1"));
         if (data->useFullPath)
-            map["usefullpath"] = "1";
+            map.insert(QLatin1String("usefullpath"), QLatin1String("1"));
         list.append(map);
     }
     setSessionValueRequested("Breakpoints", list);
@@ -349,18 +353,31 @@ void BreakHandler::loadBreakpoints()
     QVariant value;
     sessionValueRequested("Breakpoints", &value);
     QList<QVariant> list = value.toList();
-
     clear();
     foreach (const QVariant &var, list) {
         const QMap<QString, QVariant> map = var.toMap();
         BreakpointData *data = new BreakpointData(this);
-        data->fileName = map["filename"].toString();
-        data->lineNumber = map["linenumber"].toString();
-        data->condition = map["condition"].toString();
-        data->ignoreCount = map["ignorecount"].toString();
-        data->funcName = map["funcname"].toString();
-        data->enabled = !map["disabled"].toInt();
-        data->useFullPath = bool(map["usefullpath"].toInt());
+        QVariant v = map.value(QLatin1String("filename"));
+        if (v.isValid())
+            data->fileName = v.toString();
+        v = map.value(QLatin1String("linenumber"));
+        if (v.isValid())
+            data->lineNumber = v.toString();
+        v = map.value(QLatin1String("condition"));
+        if (v.isValid())
+            data->condition = v.toString();
+        v = map.value(QLatin1String("ignorecount"));
+        if (v.isValid())
+            data->ignoreCount = v.toInt();
+        v = map.value(QLatin1String("funcname"));
+        if (v.isValid())
+            data->funcName = v.toString();
+        v = map.value(QLatin1String("disabled"));
+        if (v.isValid())
+            data->enabled = !v.toInt();
+        v = map.value(QLatin1String("usefullpath"));
+        if (v.isValid())
+            data->useFullPath = bool(v.toInt());
         data->markerFileName = data->fileName;
         data->markerLineNumber = data->lineNumber.toInt();
         append(data);
diff --git a/src/plugins/debugger/cdb/cdbbreakpoint.cpp b/src/plugins/debugger/cdb/cdbbreakpoint.cpp
index a785e33febf..ee10e1e70b5 100644
--- a/src/plugins/debugger/cdb/cdbbreakpoint.cpp
+++ b/src/plugins/debugger/cdb/cdbbreakpoint.cpp
@@ -407,12 +407,19 @@ static bool setBreakPointEnabledById(CIDebugControl *ctl, unsigned long id, bool
     return true;
 }
 
+static inline QString msgCannotSetBreakAtFunction(const QString &func, const QString &why)
+{
+    return QString::fromLatin1("Cannot set a breakpoint at '%1': %2").arg(func, why);
+}
+
 // Synchronize (halted) engine breakpoints with those of the BreakHandler.
 bool CDBBreakPoint::synchronizeBreakPoints(CIDebugControl* debugControl,
                                            CIDebugSymbols *syms,
                                            BreakHandler *handler,
-                                           QString *errorMessage)
+                                           QString *errorMessage, QStringList *warnings)
 {    
+    errorMessage->clear();
+    warnings->clear();
     // Do an initial check whether we are in a state that allows
     // for modifying  breakPoints
     ULONG engineCount;
@@ -420,25 +427,29 @@ bool CDBBreakPoint::synchronizeBreakPoints(CIDebugControl* debugControl,
         *errorMessage = QString::fromLatin1("Cannot modify breakpoints: %1").arg(*errorMessage);
         return false;
     }
+    QString warning;
     // Insert new ones
     bool updateMarkers = false;
     foreach (BreakpointData *nbd, handler->insertedBreakpoints()) {
+        warning.clear();
         // Function breakpoints: Are the module names specified?
         bool breakPointOk = false;
         if (nbd->funcName.isEmpty()) {
             breakPointOk = true;
         } else {
-            switch (resolveSymbol(syms, &nbd->funcName, errorMessage)) {
+            switch (resolveSymbol(syms, &nbd->funcName, &warning)) {
             case ResolveSymbolOk:
                 breakPointOk = true;
                 break;
             case ResolveSymbolAmbiguous:
-                qWarning("Warning: %s\n", qPrintable(*errorMessage));
+                warnings->push_back(msgCannotSetBreakAtFunction(nbd->funcName, warning));
+                warning.clear();
                 breakPointOk = true;
                 break;
             case ResolveSymbolNotFound:
             case ResolveSymbolError:
-                qWarning("Warning: %s\n", qPrintable(*errorMessage));
+                warnings->push_back(msgCannotSetBreakAtFunction(nbd->funcName, warning));
+                warning.clear();
                 break;
             };
         } // function breakpoint
@@ -447,7 +458,7 @@ bool CDBBreakPoint::synchronizeBreakPoints(CIDebugControl* debugControl,
             quint64 address;
             unsigned long id;
             CDBBreakPoint ncdbbp(*nbd);
-            breakPointOk = ncdbbp.add(debugControl, &address, &id, errorMessage);            
+            breakPointOk = ncdbbp.add(debugControl, &address, &id, &warning);
             if (breakPointOk) {
                 if (debugBP)
                     qDebug() << "Added " << id << " at " << address << ncdbbp;
@@ -464,22 +475,21 @@ bool CDBBreakPoint::synchronizeBreakPoints(CIDebugControl* debugControl,
                 nbd->bpFuncName = nbd->funcName;
             }
         } // had symbol
-        if (!breakPointOk)
-            qWarning("%s\n", qPrintable(*errorMessage));
-    }
+        if (!breakPointOk && !warning.isEmpty())
+            warnings->push_back(warning);    }
     // Delete
     foreach (BreakpointData *rbd, handler->takeRemovedBreakpoints()) {
-        if (!removeBreakPointById(debugControl, rbd->bpNumber.toUInt(), errorMessage))
-            qWarning("%s\n", qPrintable(*errorMessage));
+        if (!removeBreakPointById(debugControl, rbd->bpNumber.toUInt(), &warning))
+            warnings->push_back(warning);
         delete rbd;
     }
     // Enable/Disable
     foreach (BreakpointData *ebd, handler->takeEnabledBreakpoints())
-        if (!setBreakPointEnabledById(debugControl, ebd->bpNumber.toUInt(), true, errorMessage))
-            qWarning("%s\n", qPrintable(*errorMessage));
+        if (!setBreakPointEnabledById(debugControl, ebd->bpNumber.toUInt(), true, &warning))
+            warnings->push_back(warning);
     foreach (BreakpointData *dbd, handler->takeDisabledBreakpoints())
-        if (!setBreakPointEnabledById(debugControl, dbd->bpNumber.toUInt(), false, errorMessage))
-            qWarning("%s\n", qPrintable(*errorMessage));
+        if (!setBreakPointEnabledById(debugControl, dbd->bpNumber.toUInt(), false, &warning))
+            warnings->push_back(warning);
 
     if (updateMarkers)
         handler->updateMarkers();
diff --git a/src/plugins/debugger/cdb/cdbbreakpoint.h b/src/plugins/debugger/cdb/cdbbreakpoint.h
index c739866ff09..7383687a615 100644
--- a/src/plugins/debugger/cdb/cdbbreakpoint.h
+++ b/src/plugins/debugger/cdb/cdbbreakpoint.h
@@ -73,7 +73,8 @@ struct CDBBreakPoint
     static bool getBreakPoints(CIDebugControl* debugControl, QList<CDBBreakPoint> *bps, QString *errorMessage);
     // Synchronize (halted) engine with BreakHandler.
     static bool synchronizeBreakPoints(CIDebugControl* ctl, CIDebugSymbols *syms,
-                                       BreakHandler *bh, QString *errorMessage);
+                                       BreakHandler *bh,
+                                       QString *errorMessage, QStringList *warnings);
 
     // Return a 'canonical' file (using '/' and capitalized drive letter)
     static QString canonicalSourceFile(const QString &f);
diff --git a/src/plugins/debugger/cdb/cdbdebugengine.cpp b/src/plugins/debugger/cdb/cdbdebugengine.cpp
index fbac6838d15..798f5234ff4 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine.cpp
+++ b/src/plugins/debugger/cdb/cdbdebugengine.cpp
@@ -1182,6 +1182,8 @@ void CdbDebugEngine::selectThread(int index)
 
 void CdbDebugEngine::attemptBreakpointSynchronization()
 {
+    if (!m_d->m_hDebuggeeProcess) // Sometimes called from the breakpoint Window
+        return;
     QString errorMessage;
     if (!m_d->attemptBreakpointSynchronization(&errorMessage))
         warning(msgFunctionFailed(Q_FUNC_INFO, errorMessage));
@@ -1215,10 +1217,15 @@ bool CdbDebugEnginePrivate::attemptBreakpointSynchronization(QString *errorMessa
         return true;
     }
 
-    return CDBBreakPoint::synchronizeBreakPoints(m_cif.debugControl,
+    QStringList warnings;
+    const bool ok = CDBBreakPoint::synchronizeBreakPoints(m_cif.debugControl,
                                                  m_cif.debugSymbols,
                                                  m_debuggerManagerAccess->breakHandler(),
-                                                 errorMessage);
+                                                 errorMessage, &warnings);
+    if (const int warningsCount = warnings.size())        
+        for (int w = 0; w < warningsCount; w++)
+            m_engine->warning(warnings.at(w));
+    return ok;
 }
 
 void CdbDebugEngine::reloadDisassembler()
diff --git a/src/plugins/debugger/cdb/cdbmodules.cpp b/src/plugins/debugger/cdb/cdbmodules.cpp
index a7e2e877543..7385bc27d46 100644
--- a/src/plugins/debugger/cdb/cdbmodules.cpp
+++ b/src/plugins/debugger/cdb/cdbmodules.cpp
@@ -138,6 +138,7 @@ static ResolveSymbolResult resolveSymbol(CIDebugSymbols *syms, QString *symbol,
                                          QStringList *matches,
                                          QString *errorMessage)
 {
+    errorMessage->clear();
     // Is it an incomplete symbol?
     if (symbol->contains(QLatin1Char('!')))
         return ResolveSymbolOk;
-- 
GitLab