OSDN Git Service

debugger: work on breakpoint enabling/disabling in gdb engine
authorhjk <qtc-committer@nokia.com>
Mon, 15 Nov 2010 15:22:51 +0000 (16:22 +0100)
committerhjk <qtc-committer@nokia.com>
Mon, 15 Nov 2010 15:22:51 +0000 (16:22 +0100)
src/plugins/debugger/breakhandler.cpp
src/plugins/debugger/breakhandler.h
src/plugins/debugger/breakpoint.cpp
src/plugins/debugger/breakpoint.h
src/plugins/debugger/gdb/gdbengine.cpp
src/plugins/debugger/gdb/gdbengine.h

index 8276220..444b648 100644 (file)
@@ -489,8 +489,10 @@ void BreakHandler::setter(BreakpointId id, const type &value) \
     Iterator it = m_storage.find(id); \
     QTC_ASSERT(it != m_storage.end(), \
         qDebug() << "ID" << id << "NOT KNOWN"; return); \
-    if (it->data.setter(value)) \
-        scheduleSynchronization(); \
+    if (!it->data.setter(value)) \
+        return; \
+    it->state = BreakpointChangeRequested; \
+    scheduleSynchronization(); \
 }
 
 #define PROPERTY(type, getter, setter) \
@@ -524,6 +526,7 @@ void BreakHandler::setEnabled(BreakpointId id, bool on)
     //qDebug() << "SET ENABLED: " << id << it->data.isEnabled() << on;
     if (it->data.setEnabled(on)) {
         it->destroyMarker();
+        it->state = BreakpointChangeRequested;
         updateMarker(id);
         scheduleSynchronization();
     }
@@ -579,6 +582,14 @@ void BreakHandler::ackIgnoreCount(BreakpointId id)
     updateMarker(id);
 }
 
+void BreakHandler::ackEnabled(BreakpointId id)
+{
+    Iterator it = m_storage.find(id);
+    QTC_ASSERT(it != m_storage.end(), return);
+    it->response.bpEnabled = it->data.isEnabled();
+    updateMarker(id);
+}
+
 Qt::ItemFlags BreakHandler::flags(const QModelIndex &index) const
 {
 //    switch (index.column()) {
@@ -825,10 +836,11 @@ void BreakHandler::cleanupBreakpoint(BreakpointId id)
     layoutChanged();
 }
 
-BreakpointResponse BreakHandler::response(BreakpointId id) const
+const BreakpointResponse &BreakHandler::response(BreakpointId id) const
 {
+    static BreakpointResponse dummy;
     ConstIterator it = m_storage.find(id);
-    QTC_ASSERT(it != m_storage.end(), return BreakpointResponse());
+    QTC_ASSERT(it != m_storage.end(), return dummy);
     return it->response;
 }
 
@@ -839,25 +851,6 @@ void BreakHandler::setResponse(BreakpointId id, const BreakpointResponse &data)
     it->response = BreakpointResponse(data);
     updateMarker(id);
 }
-#if 0
-void BreakHandler::notifyBreakpointAdjusted(BreakpointId id)
-{
-    QTC_ASSERT(state(id)== BreakpointChangeProceeding, /**/);
-    bp->bpNumber      = rbp.bpNumber;
-    bp->bpCondition   = rbp.bpCondition;
-    bp->bpIgnoreCount = rbp.bpIgnoreCount;
-    bp->bpFileName    = rbp.bpFileName;
-    bp->bpFullName    = rbp.bpFullName;
-    bp->bpLineNumber  = rbp.bpLineNumber;
-    bp->bpCorrectedLineNumber = rbp.bpCorrectedLineNumber;
-    bp->bpThreadSpec  = rbp.bpThreadSpec;
-    bp->bpFuncName    = rbp.bpFuncName;
-    bp->bpAddress     = rbp.bpAddress;
-    bp->bpMultiple    = rbp.bpMultiple;
-    bp->bpEnabled     = rbp.bpEnabled;
-    setState(id, BreakpointOk);
-}
-#endif
 
 void BreakHandler::BreakpointItem::destroyMarker()
 {
index 3e552d9..92093e4 100644 (file)
@@ -124,13 +124,13 @@ public:
 
     DebuggerEngine *engine(BreakpointId id) const;
     void setEngine(BreakpointId id, DebuggerEngine *engine);
-    BreakpointResponse response(BreakpointId id) const;
+    const BreakpointResponse &response(BreakpointId id) const;
     void setResponse(BreakpointId id, const BreakpointResponse &data);
 
     // Incorporate debugger feedback. No synchronization request needed.
-    // Return true if something changed.
     void ackCondition(BreakpointId id);
     void ackIgnoreCount(BreakpointId id);
+    void ackEnabled(BreakpointId id);
 
     void notifyBreakpointInsertOk(BreakpointId id);
     void notifyBreakpointInsertFailed(BreakpointId id);
index 3ca9810..fbaaeec 100644 (file)
@@ -124,13 +124,13 @@ bool BreakpointData::isLocatedAt(const QString &fileName, int lineNumber,
     return lineNumber == line && fileNameMatch(fileName, m_markerFileName);
 }
 
-bool BreakpointData::conditionsMatch(const QString &other) const
+bool BreakpointData::conditionsMatch(const QByteArray &other) const
 {
     // Some versions of gdb "beautify" the passed condition.
-    QString s1 = m_condition;
-    s1.remove(QChar(' '));
-    QString s2 = other;
-    s2.remove(QChar(' '));
+    QByteArray s1 = m_condition;
+    s1.replace(' ', "");
+    QByteArray s2 = other;
+    s2.replace(' ', "");
     return s1 == s2;
 }
 
index 81e3da2..ac239db 100644 (file)
@@ -99,7 +99,7 @@ public:
 
     bool isLocatedAt(const QString &fileName, int lineNumber,
         bool useMarkerPosition) const;
-    bool conditionsMatch(const QString &other) const;
+    bool conditionsMatch(const QByteArray &other) const;
     QString functionName() const { return m_functionName; }
     QString markerFileName() const { return m_markerFileName; }
     QString fileName() const { return m_fileName; }
index fdae9ff..21565cb 100644 (file)
@@ -2297,9 +2297,20 @@ void GdbEngine::handleBreakList(const GdbMi &table)
 
 void GdbEngine::handleBreakDisable(const GdbResponse &response)
 {
-    if (response.resultClass == GdbResultDone) {
-        breakHandler()->updateMarkers();
-    }
+    QTC_ASSERT(response.resultClass == GdbResultDone, /**/)
+    const BreakpointId id =response.cookie.toInt();
+    // This should only be the requested state.
+    QTC_ASSERT(!breakHandler()->isEnabled(id), /* Prevent later recursion */);
+    breakHandler()->ackEnabled(id);
+}
+
+void GdbEngine::handleBreakEnable(const GdbResponse &response)
+{
+    QTC_ASSERT(response.resultClass == GdbResultDone, /**/)
+    const BreakpointId id = response.cookie.toInt();
+    // This should only be the "wish" state.
+    QTC_ASSERT(breakHandler()->isEnabled(id), /* Prevent later recursion */);
+    breakHandler()->ackEnabled(id);
 }
 
 void GdbEngine::handleBreakIgnore(const GdbResponse &response)
@@ -2314,35 +2325,30 @@ void GdbEngine::handleBreakIgnore(const GdbResponse &response)
     // 29^done
     //
     // gdb 6.3 does not produce any console output
-    if (response.resultClass == GdbResultDone) {
-        QString msg = _(response.data.findChild("consolestreamoutput").data());
-        //if (msg.contains(__("Will stop next time breakpoint"))) {
-        //    data->bpIgnoreCount = _("0");
-        //} else if (msg.contains(__("Will ignore next"))) {
-        //    data->bpIgnoreCount = data->ignoreCount;
-        //}
-        // FIXME: this assumes it is doing the right thing...
-        breakHandler()->ackIgnoreCount(BreakpointId(response.cookie.toInt()));
-    }
+    QTC_ASSERT(response.resultClass == GdbResultDone, /**/)
+    QString msg = _(response.data.findChild("consolestreamoutput").data());
+    //if (msg.contains(__("Will stop next time breakpoint")))
+    //    data->bpIgnoreCount = _("0");
+    //else if (msg.contains(__("Will ignore next")))
+    //    data->bpIgnoreCount = data->ignoreCount;
+    // FIXME: this assumes it is doing the right thing...
+    BreakpointId id(response.cookie.toInt());
+    // This should only be the "wish" state.
+    QTC_ASSERT(!breakHandler()->isEnabled(id), /* prevent later recursion */);
+    breakHandler()->ackEnabled(id);
 }
 
 void GdbEngine::handleBreakCondition(const GdbResponse &response)
 {
-    const int id = response.cookie.toInt();
-    if (response.resultClass == GdbResultDone) {
-        // We just assume it was successful. Otherwise we had to parse
-        // the output stream data.
-        //qDebug() << "HANDLE BREAK CONDITION" << bpNumber << data->condition;
-        breakHandler()->ackCondition(id);
-    } else {
-        QByteArray msg = response.data.findChild("msg").data();
-        // happens on Mac
-        if (1 || msg.startsWith("Error parsing breakpoint condition. "
-                " Will try again when we hit the breakpoint.")) {
-            //qDebug() << "ERROR BREAK CONDITION" << bpNumber << data->condition;
-            breakHandler()->ackCondition(id);
-        }
-    }
+    QTC_ASSERT(response.resultClass == GdbResultDone, /**/)
+    const BreakpointId id = response.cookie.toInt();
+    // We just assume it was successful. Otherwise we had to parse
+    // the output stream data.
+    // The following happens on Mac:
+    //   QByteArray msg = response.data.findChild("msg").data();
+    //   if (1 || msg.startsWith("Error parsing breakpoint condition. "
+    //            " Will try again when we hit the breakpoint.")) {
+    breakHandler()->ackCondition(id);
 }
 
 void GdbEngine::extractDataFromInfoBreak(const QString &output, BreakpointId id)
@@ -2607,9 +2613,63 @@ void GdbEngine::insertBreakpoint(BreakpointId id)
         CB(handleBreakInsert1), id);
 }
 
-void GdbEngine::changeBreakpoint(BreakpointId)
+void GdbEngine::changeBreakpoint(BreakpointId id)
 {
-    QTC_ASSERT(false, return);
+    const BreakpointData *data0 = breakHandler()->breakpointById(id);
+    QTC_ASSERT(data0, return);
+    const BreakpointData &data = *data0;
+    const BreakpointResponse &response = breakHandler()->response(id);
+    QTC_ASSERT(response.bpNumber > 0, return);
+    const QByteArray bpnr = QByteArray::number(response.bpNumber);
+
+    if (data.condition() != response.bpCondition
+        && !data.conditionsMatch(response.bpCondition)) {
+        // Update conditions if needed.
+        postCommand("condition " + bpnr + ' '  + data.condition(),
+            NeedsStop | RebuildBreakpointModel,
+            CB(handleBreakCondition), id);
+    }
+    if (data.ignoreCount() != response.bpIgnoreCount) {
+        // Update ignorecount if needed.
+        postCommand("ignore " + bpnr + ' ' + QByteArray::number(data.ignoreCount()),
+            NeedsStop | RebuildBreakpointModel,
+            CB(handleBreakIgnore), id);
+    }
+    if (!data.isEnabled() && response.bpEnabled) {
+        postCommand("-break-disable " + bpnr,
+            NeedsStop | RebuildBreakpointModel,
+            CB(handleBreakDisable), id);
+    }
+    if (data.isEnabled() && !response.bpEnabled) {
+        postCommand("-break-enable " + bpnr,
+            NeedsStop | RebuildBreakpointModel,
+            CB(handleBreakEnable), id);
+    }
+/*
+    if (data.threadSpec() != response.bpThreadSpec)
+        // The only way to change this seems to be to re-set the bp completely.
+        //qDebug() << "FIXME: THREAD: " << data.threadSpec << response.bpThreadSpec;
+        FIXME
+        data.setThreadSpec.clear();
+        postCommand("-break-delete " + bpnr,
+            NeedsStop | RebuildBreakpointModel);
+        sendInsertBreakpoint(index);
+        continue;
+    }
+*/
+
+/*
+    if (data->bpAddress && data->bpCorrectedLineNumber == 0) {
+        // Prevent endless loop.
+        data->bpCorrectedLineNumber = -1;
+        if (debuggerCore()->boolSetting(AdjustBreakpointLocations)) {
+            postCommand(
+                "info line *0x" + QByteArray::number(data->bpAddress, 16),
+                NeedsStop | RebuildBreakpointModel,
+                CB(handleInfoLine), id)
+        }
+    }
+*/
 }
 
 void GdbEngine::removeBreakpoint(BreakpointId id)
index ce93235..49ef60c 100644 (file)
@@ -354,6 +354,7 @@ private: ////////// View & Data Stuff //////////
     void handleBreakList(const GdbMi &table);
     void handleBreakIgnore(const GdbResponse &response);
     void handleBreakDisable(const GdbResponse &response);
+    void handleBreakEnable(const GdbResponse &response);
     void handleBreakInsert1(const GdbResponse &response);
     void handleBreakInsert2(const GdbResponse &response);
     void handleBreakCondition(const GdbResponse &response);