[Lldb-commits] [lldb] 3842de4 - [lldb] [gdb-remote client] Refactor handling qSupported

Michał Górny via lldb-commits lldb-commits at lists.llvm.org
Mon Apr 12 15:23:28 PDT 2021


Author: Michał Górny
Date: 2021-04-13T00:23:07+02:00
New Revision: 3842de49f6551f597b4c7c78caa8ba7003755cec

URL: https://github.com/llvm/llvm-project/commit/3842de49f6551f597b4c7c78caa8ba7003755cec
DIFF: https://github.com/llvm/llvm-project/commit/3842de49f6551f597b4c7c78caa8ba7003755cec.diff

LOG: [lldb] [gdb-remote client] Refactor handling qSupported

Refactor the qSupported handler to split the reply into an array,
and identify features within the array rather than searching the string
for partial matches.  While at it, use StringRef.split() to process
the compression list instead of reinventing the wheel.

Switch the arguments to MaybeEnableCompression() to use an ArrayRef
of StringRefs to simplify parameter passing from GetRemoteQSupported().

Differential Revision: https://reviews.llvm.org/D100146

Added: 
    

Modified: 
    lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
    lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index c032fc20b5f3c..2db985c632db1 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -345,6 +345,9 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
   m_supports_qXfer_features_read = eLazyBoolNo;
   m_supports_qXfer_memory_map_read = eLazyBoolNo;
   m_supports_multiprocess = eLazyBoolNo;
+  m_supports_qEcho = eLazyBoolNo;
+  m_supports_QPassSignals = eLazyBoolNo;
+
   m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if
                                   // not, we assume no limit
 
@@ -362,97 +365,51 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
   if (SendPacketAndWaitForResponse(packet.GetString(), response,
                                    /*send_async=*/false) ==
       PacketResult::Success) {
-    const char *response_cstr = response.GetStringRef().data();
-
     // Hang on to the qSupported packet, so that platforms can do custom
     // configuration of the transport before attaching/launching the process.
-    m_qSupported_response = response_cstr;
-
-    if (::strstr(response_cstr, "qXfer:auxv:read+"))
-      m_supports_qXfer_auxv_read = eLazyBoolYes;
-    if (::strstr(response_cstr, "qXfer:libraries-svr4:read+"))
-      m_supports_qXfer_libraries_svr4_read = eLazyBoolYes;
-    if (::strstr(response_cstr, "augmented-libraries-svr4-read")) {
-      m_supports_qXfer_libraries_svr4_read = eLazyBoolYes; // implied
-      m_supports_augmented_libraries_svr4_read = eLazyBoolYes;
-    }
-    if (::strstr(response_cstr, "qXfer:libraries:read+"))
-      m_supports_qXfer_libraries_read = eLazyBoolYes;
-    if (::strstr(response_cstr, "qXfer:features:read+"))
-      m_supports_qXfer_features_read = eLazyBoolYes;
-    if (::strstr(response_cstr, "qXfer:memory-map:read+"))
-      m_supports_qXfer_memory_map_read = eLazyBoolYes;
-
-    // Look for a list of compressions in the features list e.g.
-    // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-
-    // deflate,lzma
-    const char *features_list = ::strstr(response_cstr, "qXfer:features:");
-    if (features_list) {
-      const char *compressions =
-          ::strstr(features_list, "SupportedCompressions=");
-      if (compressions) {
-        std::vector<std::string> supported_compressions;
-        compressions += sizeof("SupportedCompressions=") - 1;
-        const char *end_of_compressions = strchr(compressions, ';');
-        if (end_of_compressions == nullptr) {
-          end_of_compressions = strchr(compressions, '\0');
-        }
-        const char *current_compression = compressions;
-        while (current_compression < end_of_compressions) {
-          const char *next_compression_name = strchr(current_compression, ',');
-          const char *end_of_this_word = next_compression_name;
-          if (next_compression_name == nullptr ||
-              end_of_compressions < next_compression_name) {
-            end_of_this_word = end_of_compressions;
-          }
-
-          if (end_of_this_word) {
-            if (end_of_this_word == current_compression) {
-              current_compression++;
-            } else {
-              std::string this_compression(
-                  current_compression, end_of_this_word - current_compression);
-              supported_compressions.push_back(this_compression);
-              current_compression = end_of_this_word + 1;
-            }
-          } else {
-            supported_compressions.push_back(current_compression);
-            current_compression = end_of_compressions;
-          }
+    m_qSupported_response = response.GetStringRef().str();
+
+    llvm::SmallVector<llvm::StringRef, 16> server_features;
+    response.GetStringRef().split(server_features, ';');
+
+    for (auto x : server_features) {
+      if (x == "qXfer:auxv:read+")
+        m_supports_qXfer_auxv_read = eLazyBoolYes;
+      else if (x == "qXfer:libraries-svr4:read+")
+        m_supports_qXfer_libraries_svr4_read = eLazyBoolYes;
+      else if (x == "augmented-libraries-svr4-read") {
+        m_supports_qXfer_libraries_svr4_read = eLazyBoolYes; // implied
+        m_supports_augmented_libraries_svr4_read = eLazyBoolYes;
+      } else if (x == "qXfer:libraries:read+")
+        m_supports_qXfer_libraries_read = eLazyBoolYes;
+      else if (x == "qXfer:features:read+")
+        m_supports_qXfer_features_read = eLazyBoolYes;
+      else if (x == "qXfer:memory-map:read+")
+        m_supports_qXfer_memory_map_read = eLazyBoolYes;
+      else if (x == "qEcho")
+        m_supports_qEcho = eLazyBoolYes;
+      else if (x == "QPassSignals+")
+        m_supports_QPassSignals = eLazyBoolYes;
+      else if (x == "multiprocess+")
+        m_supports_multiprocess = eLazyBoolYes;
+      // Look for a list of compressions in the features list e.g.
+      // qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-
+      // deflate,lzma
+      else if (x.consume_front("SupportedCompressions=")) {
+        llvm::SmallVector<llvm::StringRef, 4> compressions;
+        x.split(compressions, ',');
+        if (!compressions.empty())
+          MaybeEnableCompression(compressions);
+      } else if (x.consume_front("PacketSize=")) {
+        StringExtractorGDBRemote packet_response(x);
+        m_max_packet_size =
+            packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX);
+        if (m_max_packet_size == 0) {
+          m_max_packet_size = UINT64_MAX; // Must have been a garbled response
+          Log *log(
+              ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+          LLDB_LOGF(log, "Garbled PacketSize spec in qSupported response");
         }
-
-        if (supported_compressions.size() > 0) {
-          MaybeEnableCompression(supported_compressions);
-        }
-      }
-    }
-
-    if (::strstr(response_cstr, "qEcho"))
-      m_supports_qEcho = eLazyBoolYes;
-    else
-      m_supports_qEcho = eLazyBoolNo;
-
-    if (::strstr(response_cstr, "QPassSignals+"))
-      m_supports_QPassSignals = eLazyBoolYes;
-    else
-      m_supports_QPassSignals = eLazyBoolNo;
-
-    if (::strstr(response_cstr, "multiprocess+"))
-      m_supports_multiprocess = eLazyBoolYes;
-    else
-      m_supports_multiprocess = eLazyBoolNo;
-
-    const char *packet_size_str = ::strstr(response_cstr, "PacketSize=");
-    if (packet_size_str) {
-      StringExtractorGDBRemote packet_response(packet_size_str +
-                                               strlen("PacketSize="));
-      m_max_packet_size =
-          packet_response.GetHexMaxU64(/*little_endian=*/false, UINT64_MAX);
-      if (m_max_packet_size == 0) {
-        m_max_packet_size = UINT64_MAX; // Must have been a garbled response
-        Log *log(
-            ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
-        LLDB_LOGF(log, "Garbled PacketSize spec in qSupported response");
       }
     }
   }
@@ -1036,7 +993,7 @@ bool GDBRemoteCommunicationClient::GetGDBServerVersion() {
 }
 
 void GDBRemoteCommunicationClient::MaybeEnableCompression(
-    std::vector<std::string> supported_compressions) {
+    llvm::ArrayRef<llvm::StringRef> supported_compressions) {
   CompressionType avail_type = CompressionType::None;
   std::string avail_name;
 

diff  --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 96519d3077063..d559882ed7dc6 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -601,7 +601,8 @@ class GDBRemoteCommunicationClient : public GDBRemoteClientBase {
 
   // Given the list of compression types that the remote debug stub can support,
   // possibly enable compression if we find an encoding we can handle.
-  void MaybeEnableCompression(std::vector<std::string> supported_compressions);
+  void MaybeEnableCompression(
+      llvm::ArrayRef<llvm::StringRef> supported_compressions);
 
   bool DecodeProcessInfoResponse(StringExtractorGDBRemote &response,
                                  ProcessInstanceInfo &process_info);


        


More information about the lldb-commits mailing list