base: increase the GDB buffer size dynamically
authorCiro Santilli <ciro.santilli@arm.com>
Wed, 14 Nov 2018 00:00:01 +0000 (00:00 +0000)
committerCiro Santilli <ciro.santilli@arm.com>
Mon, 3 Dec 2018 10:43:15 +0000 (10:43 +0000)
The size was not large enough for the 'G' packet on aarch64, which the
client sends to set registers.

This would lead to the stub not to be able to find the end of the input
packet and keep waiting forever.

Change-Id: Icb149f15a6c769371ebcb6ec5fbebc6170c31fc6
Reviewed-on: https://gem5-review.googlesource.com/c/14497
Reviewed-by: Gabe Black <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>

src/base/remote_gdb.cc
src/base/remote_gdb.hh

index 37ecef97caf44b130ce34f512f896b473e925d0a..2c54f5b5f4537270e417a7580060c879facb27ba 100644 (file)
@@ -152,8 +152,6 @@ static const char GDBEnd = '#';
 static const char GDBGoodP = '+';
 static const char GDBBadP = '-';
 
-static const int GDBPacketBufLen = 1024;
-
 vector<BaseRemoteGDB *> debuggers;
 
 class HardBreakpoint : public PCEvent
@@ -441,20 +439,19 @@ BaseRemoteGDB::trap(int type)
     regCachePtr = gdbRegs();
     regCachePtr->getRegs(tc);
 
-    char data[GDBPacketBufLen + 1];
     GdbCommand::Context cmdCtx;
     cmdCtx.type = type;
-    cmdCtx.data = &data[1];
+    std::vector<char> data;
 
     for (;;) {
         try {
-            size_t datalen = recv(data, sizeof(data));
-            if (datalen < 1)
+            recv(data);
+            if (data.size() == 1)
                 throw BadClient();
-
-            data[datalen] = 0; // Sentinel
             cmdCtx.cmd_byte = data[0];
-            cmdCtx.len = datalen - 1;
+            cmdCtx.data = data.data() + 1;
+            // One for sentinel, one for cmd_byte.
+            cmdCtx.len = data.size() - 2;
 
             auto cmdIt = command_map.find(cmdCtx.cmd_byte);
             if (cmdIt == command_map.end()) {
@@ -521,41 +518,31 @@ BaseRemoteGDB::putbyte(uint8_t b)
 }
 
 // Receive a packet from gdb
-int
-BaseRemoteGDB::recv(char *bp, int maxlen)
+void
+BaseRemoteGDB::recv(std::vector<char>& bp)
 {
-    char *p;
     uint8_t c;
     int csum;
-    int len;
+    bp.resize(0);
 
     do {
-        p = bp;
-        csum = len = 0;
+        csum = 0;
         // Find the beginning of a packet
         while ((c = getbyte()) != GDBStart);
 
         // Read until you find the end of the data in the packet, and keep
         // track of the check sum.
-        while (len < maxlen) {
+        while (true) {
             c = getbyte();
             if (c == GDBEnd)
                 break;
             c &= 0x7f;
             csum += c;
-            *p++ = c;
-            len++;
+            bp.push_back(c);
         }
 
-        // Mask the check sum, and terminate the command string.
+        // Mask the check sum.
         csum &= 0xff;
-        *p = '\0';
-
-        // If the command was too long, report an error.
-        if (len >= maxlen) {
-            putbyte(GDBBadP);
-            continue;
-        }
 
         // Bring in the checksum. If the check sum matches, csum will be 0.
         csum -= digit2i(getbyte()) * 16;
@@ -566,21 +553,20 @@ BaseRemoteGDB::recv(char *bp, int maxlen)
             // Report that the packet was received correctly
             putbyte(GDBGoodP);
             // Sequence present?
-            if (bp[2] == ':') {
+            if (bp.size() > 2 && bp[2] == ':') {
                 putbyte(bp[0]);
                 putbyte(bp[1]);
-                len -= 3;
-                memcpy(bp, bp+3, len);
+                auto begin = std::begin(bp);
+                bp.erase(begin, std::next(begin, 3));
             }
             break;
         }
         // Otherwise, report that there was a mistake.
         putbyte(GDBBadP);
     } while (1);
-
-    DPRINTF(GDBRecv, "recv:  %s\n", bp);
-
-    return len;
+    // Sentinel.
+    bp.push_back('\0');
+    DPRINTF(GDBRecv, "recv:  %s\n", bp.data());
 }
 
 // Send a packet to gdb
index 27b4ab488f4f1b0c4e3906ed6aa8004087c4d7eb..82a1e15bca610d6527be7593bdb2d85dbe04dea5 100644 (file)
@@ -171,7 +171,7 @@ class BaseRemoteGDB
     uint8_t getbyte();
     void putbyte(uint8_t b);
 
-    int recv(char *data, int len);
+    void recv(std::vector<char> &bp);
     void send(const char *data);
 
     /*