From 40d54a84dc51f12a1e2c84bd83b154455d7c3204 Mon Sep 17 00:00:00 2001
From: hjk <qtc-committer@nokia.com>
Date: Mon, 14 Sep 2009 09:46:34 +0200
Subject: [PATCH] debugger: work on trk integration

---
 src/plugins/debugger/gdb/gdbengine.cpp     | 111 +++++++++++----------
 src/plugins/debugger/gdb/trkgdbadapter.cpp |  51 +++++++---
 src/plugins/debugger/gdb/trkgdbadapter.h   |   1 +
 3 files changed, 95 insertions(+), 68 deletions(-)

diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index c5248057709..8154ec4e081 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -1265,7 +1265,8 @@ void GdbEngine::reloadFullStack()
 void GdbEngine::reloadStack()
 {
     QString cmd = _("-stack-list-frames");
-    if (int stackDepth = theDebuggerAction(MaximalStackDepth)->value().toInt())
+    int stackDepth = theDebuggerAction(MaximalStackDepth)->value().toInt();
+    if (stackDepth && !m_gdbAdapter->isAdapter())
         cmd += _(" 0 ") + QString::number(stackDepth);
     postCommand(cmd, WatchUpdate, CB(handleStackListFrames), false);
 }
@@ -2493,64 +2494,66 @@ void GdbEngine::handleStackSelectThread(const GdbResultRecord &, const QVariant
 
 void GdbEngine::handleStackListFrames(const GdbResultRecord &record, const QVariant &cookie)
 {
-    bool isFull = cookie.toBool();
-    QList<StackFrame> stackFrames;
-
-    const GdbMi stack = record.data.findChild("stack");
-    stack.toString();
-    if (!stack.isValid()) {
-        qDebug() << "FIXME: stack:" << stack.toString();
-        return;
-    }
-
-    int topFrame = -1;
-
-    int n = stack.childCount();
-    for (int i = 0; i != n; ++i) {
-        //qDebug() << "HANDLING FRAME:" << stack.childAt(i).toString();
-        const GdbMi frameMi = stack.childAt(i);
-        StackFrame frame(i);
-        QStringList files;
-        files.append(QFile::decodeName(frameMi.findChild("fullname").data()));
-        files.append(QFile::decodeName(frameMi.findChild("file").data()));
-        frame.file = fullName(files);
-        frame.function = _(frameMi.findChild("func").data());
-        frame.from = _(frameMi.findChild("from").data());
-        frame.line = frameMi.findChild("line").data().toInt();
-        frame.address = _(frameMi.findChild("addr").data());
-
-        stackFrames.append(frame);
+    if (record.resultClass == GdbResultDone) {
+        bool isFull = cookie.toBool();
+        QList<StackFrame> stackFrames;
 
-#if defined(Q_OS_WIN)
-        const bool isBogus =
-            // Assume this is wrong and points to some strange stl_algobase
-            // implementation. Happens on Karsten's XP system with Gdb 5.50
-            (frame.file.endsWith(__("/bits/stl_algobase.h")) && frame.line == 150)
-            // Also wrong. Happens on Vista with Gdb 5.50
-               || (frame.function == __("operator new") && frame.line == 151);
-
-        // immediately leave bogus frames
-        if (topFrame == -1 && isBogus) {
-            postCommand(_("-exec-finish"));
+        GdbMi stack = record.data.findChild("stack");
+        if (!stack.isValid()) {
+            qDebug() << "FIXME: stack:" << stack.toString();
             return;
         }
 
-#endif
+        int topFrame = -1;
+
+        int n = stack.childCount();
+        for (int i = 0; i != n; ++i) {
+            //qDebug() << "HANDLING FRAME:" << stack.childAt(i).toString();
+            const GdbMi frameMi = stack.childAt(i);
+            StackFrame frame(i);
+            QStringList files;
+            files.append(QFile::decodeName(frameMi.findChild("fullname").data()));
+            files.append(QFile::decodeName(frameMi.findChild("file").data()));
+            frame.file = fullName(files);
+            frame.function = _(frameMi.findChild("func").data());
+            frame.from = _(frameMi.findChild("from").data());
+            frame.line = frameMi.findChild("line").data().toInt();
+            frame.address = _(frameMi.findChild("addr").data());
+
+            stackFrames.append(frame);
+
+            #if defined(Q_OS_WIN)
+            const bool isBogus =
+                // Assume this is wrong and points to some strange stl_algobase
+                // implementation. Happens on Karsten's XP system with Gdb 5.50
+                (frame.file.endsWith(__("/bits/stl_algobase.h")) && frame.line == 150)
+                // Also wrong. Happens on Vista with Gdb 5.50
+                   || (frame.function == __("operator new") && frame.line == 151);
+
+            // immediately leave bogus frames
+            if (topFrame == -1 && isBogus) {
+                postCommand(_("-exec-finish"));
+                return;
+            }
+            #endif
 
-        // Initialize top frame to the first valid frame
-        const bool isValid = !frame.file.isEmpty() && !frame.function.isEmpty();
-        if (isValid && topFrame == -1)
-            topFrame = i;
-    }
+            // Initialize top frame to the first valid frame
+            const bool isValid = !frame.file.isEmpty() && !frame.function.isEmpty();
+            if (isValid && topFrame == -1)
+                topFrame = i;
+        }
 
-    bool canExpand = !isFull 
-        && (n >= theDebuggerAction(MaximalStackDepth)->value().toInt());
-    theDebuggerAction(ExpandStack)->setEnabled(canExpand);
-    qq->stackHandler()->setFrames(stackFrames, canExpand);
+        bool canExpand = !isFull 
+            && (n >= theDebuggerAction(MaximalStackDepth)->value().toInt());
+        theDebuggerAction(ExpandStack)->setEnabled(canExpand);
+        qq->stackHandler()->setFrames(stackFrames, canExpand);
 
-    if (topFrame != -1 || theDebuggerBoolSetting(StepByInstruction)) {
-        const StackFrame &frame = qq->stackHandler()->currentFrame();
-        q->gotoLocation(frame, true);
+        if (topFrame != -1 || theDebuggerBoolSetting(StepByInstruction)) {
+            const StackFrame &frame = qq->stackHandler()->currentFrame();
+            q->gotoLocation(frame, true);
+        }
+    } else if (record.resultClass == GdbResultError) {
+        qDebug() << "STACK FAILED: " << record.toString();
     }
 }
 
@@ -3619,8 +3622,8 @@ void GdbEngine::updateLocals()
 {
     // Asynchronous load of injected library, initialize in first stop
     if (m_dumperInjectionLoad && m_debuggingHelperState == DebuggingHelperLoadTried
-        && m_dumperHelper.typeCount() == 0
-        && q->inferiorPid() > 0)
+            && m_dumperHelper.typeCount() == 0
+            && q->inferiorPid() > 0)
         tryQueryDebuggingHelpers();
 
     m_pendingRequests = 0;
diff --git a/src/plugins/debugger/gdb/trkgdbadapter.cpp b/src/plugins/debugger/gdb/trkgdbadapter.cpp
index 7117ed01a2d..45bcce5fdf3 100644
--- a/src/plugins/debugger/gdb/trkgdbadapter.cpp
+++ b/src/plugins/debugger/gdb/trkgdbadapter.cpp
@@ -71,15 +71,13 @@ static QByteArray dumpRegister(int n, uint value)
 namespace Debugger {
 namespace Internal {
 
-trk::Endianness m_registerEndianness = LittleEndian;
-
 TrkGdbAdapter::TrkGdbAdapter()
 {
     m_running = false;
     m_gdbAckMode = true;
     m_verbose = 2;
     m_serialFrame = false;
-    m_bufferedMemoryRead = false;
+    m_bufferedMemoryRead = true;
     m_rfcommDevice = "/dev/rfcomm0";
 
     uid_t userId = getuid();
@@ -530,18 +528,18 @@ void TrkGdbAdapter::handleGdbServerCommand(const QByteArray &cmd)
         QByteArray logMsg = "Read Register";
         if (registerNumber == RegisterPSGdb) {
             QByteArray ba;
-            appendInt(&ba, m_snapshot.registers[RegisterPSTrk], m_registerEndianness);
+            appendInt(&ba, m_snapshot.registers[RegisterPSTrk], LittleEndian);
             logMsg += dumpRegister(registerNumber, m_snapshot.registers[RegisterPSTrk]);
             sendGdbServerMessage(ba.toHex(), logMsg);
-        } else if (registerNumber < RegisterCount) {
+        } else if (registerNumber < 16) {
             QByteArray ba;
-            appendInt(&ba, m_snapshot.registers[registerNumber], m_registerEndianness);
+            appendInt(&ba, m_snapshot.registers[registerNumber], LittleEndian);
             logMsg += dumpRegister(registerNumber, m_snapshot.registers[registerNumber]);
             sendGdbServerMessage(ba.toHex(), logMsg);
         } else {
-            sendGdbServerMessage("0000", "read single unknown register #"
-                + QByteArray::number(registerNumber));
-            //sendGdbServerMessage("E01", "read single unknown register");
+            //sendGdbServerMessage("0000", "read single unknown register #"
+            //    + QByteArray::number(registerNumber));
+            sendGdbServerMessage("E01", "read single unknown register");
         }
     }
 
@@ -801,7 +799,12 @@ void TrkGdbAdapter::handleTrkResult(const TrkResult &result)
                 // query is pending, queue instead
                 if (m_running) {
                     m_running = false;
-                    sendGdbServerMessage("S05", "Target stopped");
+                    // We almost always need register values, so get them
+                    // now before informing gdb about the stop. In theory
+                    //sendGdbServerMessage("S05", "Target stopped");
+                    sendTrkMessage(0x12,
+                        TrkCB(handleAndReportReadRegistersAfterStop),
+                        trkReadRegisterMessage());
                 }
             } else {
                 logMessage(QLatin1String("Ignoring stop at 0"));
@@ -952,8 +955,7 @@ void TrkGdbAdapter::handleAndReportReadRegisters(const TrkResult &result)
     handleReadRegisters(result);
     QByteArray ba;
     for (int i = 0; i < 16; ++i) {
-        const uint reg = m_registerEndianness == LittleEndian
-            ? swapEndian(m_snapshot.registers[i]) : m_snapshot.registers[i];
+        const uint reg = swapEndian(m_snapshot.registers[i]);
         ba += hexNumber(reg, 8);
     }
     QByteArray logMsg = "REGISTER CONTENTS: ";
@@ -966,6 +968,27 @@ void TrkGdbAdapter::handleAndReportReadRegisters(const TrkResult &result)
     sendGdbServerMessage(ba, logMsg);
 }
 
+static void appendRegister(QByteArray *ba, uint regno, uint value)
+{
+    ba->append(hexNumber(regno, 2));
+    ba->append(':');
+    ba->append(hexNumber(swapEndian(value), 8));
+    ba->append(';');
+}
+
+void TrkGdbAdapter::handleAndReportReadRegistersAfterStop(const TrkResult &result)
+{
+    handleReadRegisters(result);
+    QByteArray ba = "T05";
+    for (int i = 0; i < 16; ++i)
+        appendRegister(&ba, i, m_snapshot.registers[i]);
+    //for (int i = 16; i < 25; ++i)
+    //    appendRegister(&ba, i, 0x0);
+    appendRegister(&ba, RegisterPSGdb, m_snapshot.registers[RegisterPSTrk]);
+    qDebug() << "TrkGdbAdapter::handleAndReportReadRegistersAfterStop" << ba;
+    sendGdbServerMessage(ba, "Registers");
+}
+
 static QString msgMemoryReadError(int code, uint addr, uint len = 0)
 {
     const QString lenS = len ? QString::number(len) : QLatin1String("<unknown>");
@@ -1271,8 +1294,8 @@ void TrkGdbAdapter::startGdb()
         return;
     }
 
-    logMessage(QString("Gdb server running on %1.\nRegister endianness: %3.")
-        .arg(m_gdbServerName).arg(m_registerEndianness));
+    logMessage(QString("Gdb server running on %1.\nLittle endian assumed.")
+        .arg(m_gdbServerName));
 
     connect(&m_gdbServer, SIGNAL(newConnection()),
         this, SLOT(handleGdbConnection()));
diff --git a/src/plugins/debugger/gdb/trkgdbadapter.h b/src/plugins/debugger/gdb/trkgdbadapter.h
index afb1be29e36..e8ff7a8dafc 100644
--- a/src/plugins/debugger/gdb/trkgdbadapter.h
+++ b/src/plugins/debugger/gdb/trkgdbadapter.h
@@ -158,6 +158,7 @@ public:
 
     void handleAndReportCreateProcess(const TrkResult &result);
     void handleAndReportReadRegisters(const TrkResult &result);
+    void handleAndReportReadRegistersAfterStop(const TrkResult &result);
     QByteArray memoryReadLogMessage(uint addr, uint len, const QByteArray &ba) const;
     QByteArray trkContinueMessage();
     QByteArray trkReadRegisterMessage();
-- 
GitLab