Author: Matej Košík
Date: 2026-02-24T13:08:04Z
New Revision: 75383421c1c6b8a33e762b42b83242dbd85e466e

URL: 
https://github.com/llvm/llvm-project/commit/75383421c1c6b8a33e762b42b83242dbd85e466e
DIFF: 
https://github.com/llvm/llvm-project/commit/75383421c1c6b8a33e762b42b83242dbd85e466e.diff

LOG: [lldb] generalize the GDBRemoteCommunicationClient::GetVContSupported 
method (#182287)

This is a conservative generalization of the
`GDBRemoteCommunicationClient::GetVContSupported` method so that:
- the new version of this method handles the reply to the `vCont?`
packet the same way as the original version of this method
- the new version of this method can be easily adapted to situation when
the actions are represented by multiple letters.

Imagine that, in addition to the [existing
actions](https://sourceware.org/gdb/current/onlinedocs/gdb.html/Packets.html#vCont-packet):
- `c`
- `C`
- `s`
- `S`
- `t`
- `r`

the other party would also advertise that it supports (e.g.) `sc` action
(meaning e.g. that we can ask the other party to step into microcode).

The new version of this method can be easily adapted to handle such a
case without compromising correct handling of the original actions
represented by single characters.

---------

Co-authored-by: Matej Košík <[email protected]>
Co-authored-by: Jonas Devlieghere <[email protected]>

Added: 
    

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

Removed: 
    


################################################################################
diff  --git 
a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp 
b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 11f164c2426ce..738e4013b6154 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -480,7 +480,9 @@ bool 
GDBRemoteCommunicationClient::GetThreadSuffixSupported() {
   }
   return m_supports_thread_suffix;
 }
-bool GDBRemoteCommunicationClient::GetVContSupported(char flavor) {
+
+bool GDBRemoteCommunicationClient::GetVContSupported(llvm::StringRef flavor) {
+  assert(!flavor.empty());
   if (m_supports_vCont_c == eLazyBoolCalculate) {
     StringExtractorGDBRemote response;
     m_supports_vCont_any = eLazyBoolNo;
@@ -491,18 +493,16 @@ bool GDBRemoteCommunicationClient::GetVContSupported(char 
flavor) {
     m_supports_vCont_S = eLazyBoolNo;
     if (SendPacketAndWaitForResponse("vCont?", response) ==
         PacketResult::Success) {
-      const char *response_cstr = response.GetStringRef().data();
-      if (::strstr(response_cstr, ";c"))
-        m_supports_vCont_c = eLazyBoolYes;
-
-      if (::strstr(response_cstr, ";C"))
-        m_supports_vCont_C = eLazyBoolYes;
-
-      if (::strstr(response_cstr, ";s"))
-        m_supports_vCont_s = eLazyBoolYes;
-
-      if (::strstr(response_cstr, ";S"))
-        m_supports_vCont_S = eLazyBoolYes;
+      for (llvm::StringRef token : llvm::split(response.GetStringRef(), ';')) {
+        if (token == "c")
+          m_supports_vCont_c = eLazyBoolYes;
+        if (token == "C")
+          m_supports_vCont_C = eLazyBoolYes;
+        if (token == "s")
+          m_supports_vCont_s = eLazyBoolYes;
+        if (token == "S")
+          m_supports_vCont_S = eLazyBoolYes;
+      }
 
       if (m_supports_vCont_c == eLazyBoolYes &&
           m_supports_vCont_C == eLazyBoolYes &&
@@ -520,23 +520,14 @@ bool GDBRemoteCommunicationClient::GetVContSupported(char 
flavor) {
     }
   }
 
-  switch (flavor) {
-  case 'a':
-    return m_supports_vCont_any;
-  case 'A':
-    return m_supports_vCont_all;
-  case 'c':
-    return m_supports_vCont_c;
-  case 'C':
-    return m_supports_vCont_C;
-  case 's':
-    return m_supports_vCont_s;
-  case 'S':
-    return m_supports_vCont_S;
-  default:
-    break;
-  }
-  return false;
+  return llvm::StringSwitch<bool>(flavor)
+      .Case("a", m_supports_vCont_any)
+      .Case("A", m_supports_vCont_all)
+      .Case("c", m_supports_vCont_c)
+      .Case("C", m_supports_vCont_C)
+      .Case("s", m_supports_vCont_s)
+      .Case("S", m_supports_vCont_S)
+      .Default(false);
 }
 
 GDBRemoteCommunication::PacketResult

diff  --git 
a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h 
b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index ad590a25d0f16..d04f6370bb6ae 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -214,7 +214,7 @@ class GDBRemoteCommunicationClient : public 
GDBRemoteClientBase {
 
   void GetRemoteQSupported();
 
-  bool GetVContSupported(char flavor);
+  bool GetVContSupported(llvm::StringRef flavor);
 
   bool GetpPacketSupported(lldb::tid_t tid);
 
@@ -262,9 +262,9 @@ class GDBRemoteCommunicationClient : public 
GDBRemoteClientBase {
 
   bool GetGroupName(uint32_t gid, std::string &name);
 
-  bool HasFullVContSupport() { return GetVContSupported('A'); }
+  bool HasFullVContSupport() { return GetVContSupported("A"); }
 
-  bool HasAnyVContSupport() { return GetVContSupported('a'); }
+  bool HasAnyVContSupport() { return GetVContSupported("a"); }
 
   bool GetStopReply(StringExtractorGDBRemote &response);
 

diff  --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp 
b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 57d86ef71eecc..75b28f90d08b8 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -925,7 +925,7 @@ Status 
ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) {
   m_gdb_comm.GetThreadSuffixSupported();
   m_gdb_comm.GetListThreadsInStopReplySupported();
   m_gdb_comm.GetHostInfo();
-  m_gdb_comm.GetVContSupported('c');
+  m_gdb_comm.GetVContSupported("c");
   m_gdb_comm.GetVAttachOrWaitSupported();
   m_gdb_comm.EnableErrorStringInPacket();
 
@@ -1305,7 +1305,7 @@ Status ProcessGDBRemote::DoResume(RunDirection direction) 
{
         continue_packet.PutCString("vCont");
 
         if (!m_continue_c_tids.empty()) {
-          if (m_gdb_comm.GetVContSupported('c')) {
+          if (m_gdb_comm.GetVContSupported("c")) {
             for (tid_collection::const_iterator
                      t_pos = m_continue_c_tids.begin(),
                      t_end = m_continue_c_tids.end();
@@ -1316,7 +1316,7 @@ Status ProcessGDBRemote::DoResume(RunDirection direction) 
{
         }
 
         if (!continue_packet_error && !m_continue_C_tids.empty()) {
-          if (m_gdb_comm.GetVContSupported('C')) {
+          if (m_gdb_comm.GetVContSupported("C")) {
             for (tid_sig_collection::const_iterator
                      s_pos = m_continue_C_tids.begin(),
                      s_end = m_continue_C_tids.end();
@@ -1328,7 +1328,7 @@ Status ProcessGDBRemote::DoResume(RunDirection direction) 
{
         }
 
         if (!continue_packet_error && !m_continue_s_tids.empty()) {
-          if (m_gdb_comm.GetVContSupported('s')) {
+          if (m_gdb_comm.GetVContSupported("s")) {
             for (tid_collection::const_iterator
                      t_pos = m_continue_s_tids.begin(),
                      t_end = m_continue_s_tids.end();
@@ -1339,7 +1339,7 @@ Status ProcessGDBRemote::DoResume(RunDirection direction) 
{
         }
 
         if (!continue_packet_error && !m_continue_S_tids.empty()) {
-          if (m_gdb_comm.GetVContSupported('S')) {
+          if (m_gdb_comm.GetVContSupported("S")) {
             for (tid_sig_collection::const_iterator
                      s_pos = m_continue_S_tids.begin(),
                      s_end = m_continue_S_tids.end();

diff  --git 
a/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp 
b/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
index 966b37e09ee55..a5156326a1447 100644
--- a/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
+++ b/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
@@ -77,6 +77,54 @@ class GDBRemoteCommunicationClientTest : public 
GDBRemoteTest {
   MockServer server;
 };
 
+TEST_F(GDBRemoteCommunicationClientTest, vCont_c) {
+  std::future<bool> write_result = std::async(
+      std::launch::async, [&] { return client.GetVContSupported("c"); });
+  HandlePacket(server, "vCont?", "$vCont;c#16");
+  ASSERT_TRUE(write_result.get());
+  ASSERT_FALSE(client.GetVContSupported("C"));
+  ASSERT_FALSE(client.GetVContSupported("s"));
+  ASSERT_FALSE(client.GetVContSupported("S"));
+  ASSERT_TRUE(client.GetVContSupported("a"));
+  ASSERT_FALSE(client.GetVContSupported("A"));
+}
+
+TEST_F(GDBRemoteCommunicationClientTest, vCont_C) {
+  std::future<bool> write_result = std::async(
+      std::launch::async, [&] { return client.GetVContSupported("c"); });
+  HandlePacket(server, "vCont?", "$vCont;C#16");
+  ASSERT_FALSE(write_result.get());
+  ASSERT_TRUE(client.GetVContSupported("C"));
+  ASSERT_FALSE(client.GetVContSupported("s"));
+  ASSERT_FALSE(client.GetVContSupported("S"));
+  ASSERT_TRUE(client.GetVContSupported("a"));
+  ASSERT_FALSE(client.GetVContSupported("A"));
+}
+
+TEST_F(GDBRemoteCommunicationClientTest, vCont_c_C) {
+  std::future<bool> write_result = std::async(
+      std::launch::async, [&] { return client.GetVContSupported("c"); });
+  HandlePacket(server, "vCont?", "$vCont;c;C#16");
+  ASSERT_TRUE(write_result.get());
+  ASSERT_TRUE(client.GetVContSupported("C"));
+  ASSERT_FALSE(client.GetVContSupported("s"));
+  ASSERT_FALSE(client.GetVContSupported("S"));
+  ASSERT_TRUE(client.GetVContSupported("a"));
+  ASSERT_FALSE(client.GetVContSupported("A"));
+}
+
+TEST_F(GDBRemoteCommunicationClientTest, vCont_cC_notAFeature) {
+  std::future<bool> write_result = std::async(
+      std::launch::async, [&] { return client.GetVContSupported("c"); });
+  HandlePacket(server, "vCont?", "$vCont;cC;notAFeature#16");
+  ASSERT_FALSE(write_result.get());
+  ASSERT_FALSE(client.GetVContSupported("C"));
+  ASSERT_FALSE(client.GetVContSupported("s"));
+  ASSERT_FALSE(client.GetVContSupported("S"));
+  ASSERT_FALSE(client.GetVContSupported("a"));
+  ASSERT_FALSE(client.GetVContSupported("A"));
+}
+
 TEST_F(GDBRemoteCommunicationClientTest, WriteRegister) {
   const lldb::tid_t tid = 0x47;
   const uint32_t reg_num = 4;


        
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to