[Lldb-commits] [lldb] ccb9d4d - [lldb] [gdb-remote] Include PID in vCont packets if multiprocess

Michał Górny via lldb-commits lldb-commits at lists.llvm.org
Fri Aug 19 00:02:41 PDT 2022


Author: Michał Górny
Date: 2022-08-19T09:02:20+02:00
New Revision: ccb9d4d4addc2fb2aa94cf776d43d8be35365272

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

LOG: [lldb] [gdb-remote] Include PID in vCont packets if multiprocess

Try to always send vCont packets and include the PID in them if running
multiprocess.  This is necessary to ensure that with the upcoming full
multiprocess support always resumes the correct process without having
to resort to the legacy Hc packets.

Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.llvm.org/D131758

Added: 
    lldb/test/API/functionalities/gdb_remote_client/TestContinue.py

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

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 29417b35fde3a..11d0fec1926ab 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -181,6 +181,12 @@ bool GDBRemoteCommunicationClient::GetQXferSigInfoReadSupported() {
   return m_supports_qXfer_siginfo_read == eLazyBoolYes;
 }
 
+bool GDBRemoteCommunicationClient::GetMultiprocessSupported() {
+  if (m_supports_memory_tagging == eLazyBoolCalculate)
+    GetRemoteQSupported();
+  return m_supports_multiprocess == eLazyBoolYes;
+}
+
 uint64_t GDBRemoteCommunicationClient::GetRemoteMaxPacketSize() {
   if (m_max_packet_size == 0) {
     GetRemoteQSupported();
@@ -1514,7 +1520,7 @@ Status GDBRemoteCommunicationClient::Detach(bool keep_stopped,
     }
   }
 
-  if (m_supports_multiprocess) {
+  if (GetMultiprocessSupported()) {
     // Some servers (e.g. qemu) require specifying the PID even if only a single
     // process is running.
     if (pid == LLDB_INVALID_PROCESS_ID)

diff  --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 3a62747603f6d..4e89ade772ad3 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -339,6 +339,8 @@ class GDBRemoteCommunicationClient : public GDBRemoteClientBase {
 
   bool GetQXferSigInfoReadSupported();
 
+  bool GetMultiprocessSupported();
+
   LazyBool SupportsAllocDeallocMemory() // const
   {
     // Uncomment this to have lldb pretend the debug server doesn't respond to

diff  --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 30fb27932d192..0c876a8fd703e 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -1186,11 +1186,15 @@ Status ProcessGDBRemote::DoResume() {
     StreamString continue_packet;
     bool continue_packet_error = false;
     if (m_gdb_comm.HasAnyVContSupport()) {
+      std::string pid_prefix;
+      if (m_gdb_comm.GetMultiprocessSupported())
+        pid_prefix = llvm::formatv("p{0:x-}.", GetID());
+
       if (m_continue_c_tids.size() == num_threads ||
           (m_continue_c_tids.empty() && m_continue_C_tids.empty() &&
            m_continue_s_tids.empty() && m_continue_S_tids.empty())) {
-        // All threads are continuing, just send a "c" packet
-        continue_packet.PutCString("c");
+        // All threads are continuing
+        continue_packet.Format("vCont;c:{0}-1", pid_prefix);
       } else {
         continue_packet.PutCString("vCont");
 
@@ -1200,7 +1204,7 @@ Status ProcessGDBRemote::DoResume() {
                      t_pos = m_continue_c_tids.begin(),
                      t_end = m_continue_c_tids.end();
                  t_pos != t_end; ++t_pos)
-              continue_packet.Printf(";c:%4.4" PRIx64, *t_pos);
+              continue_packet.Format(";c:{0}{1:x-}", pid_prefix, *t_pos);
           } else
             continue_packet_error = true;
         }
@@ -1211,8 +1215,8 @@ Status ProcessGDBRemote::DoResume() {
                      s_pos = m_continue_C_tids.begin(),
                      s_end = m_continue_C_tids.end();
                  s_pos != s_end; ++s_pos)
-              continue_packet.Printf(";C%2.2x:%4.4" PRIx64, s_pos->second,
-                                     s_pos->first);
+              continue_packet.Format(";C{0:x-2}:{1}{2:x-}", s_pos->second,
+                                     pid_prefix, s_pos->first);
           } else
             continue_packet_error = true;
         }
@@ -1223,7 +1227,7 @@ Status ProcessGDBRemote::DoResume() {
                      t_pos = m_continue_s_tids.begin(),
                      t_end = m_continue_s_tids.end();
                  t_pos != t_end; ++t_pos)
-              continue_packet.Printf(";s:%4.4" PRIx64, *t_pos);
+              continue_packet.Format(";s:{0}{1:x-}", pid_prefix, *t_pos);
           } else
             continue_packet_error = true;
         }
@@ -1234,8 +1238,8 @@ Status ProcessGDBRemote::DoResume() {
                      s_pos = m_continue_S_tids.begin(),
                      s_end = m_continue_S_tids.end();
                  s_pos != s_end; ++s_pos)
-              continue_packet.Printf(";S%2.2x:%4.4" PRIx64, s_pos->second,
-                                     s_pos->first);
+              continue_packet.Format(";S{0:x-2}:{1}{2:x-}", s_pos->second,
+                                     pid_prefix, s_pos->first);
           } else
             continue_packet_error = true;
         }

diff  --git a/lldb/test/API/functionalities/gdb_remote_client/TestContinue.py b/lldb/test/API/functionalities/gdb_remote_client/TestContinue.py
new file mode 100644
index 0000000000000..14147fb5b2bfe
--- /dev/null
+++ b/lldb/test/API/functionalities/gdb_remote_client/TestContinue.py
@@ -0,0 +1,87 @@
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+from lldbsuite.test.gdbclientutils import *
+from lldbsuite.test.lldbgdbclient import GDBRemoteTestBase
+
+
+class TestContinue(GDBRemoteTestBase):
+    class BaseResponder(MockGDBServerResponder):
+        def qSupported(self, client_supported):
+            return "PacketSize=3fff;QStartNoAckMode+;multiprocess+"
+
+        def qfThreadInfo(self):
+            return "mp400.401"
+
+        def haltReason(self):
+            return "S13"
+
+        def cont(self):
+            return "W01"
+
+        def other(self, packet):
+            if packet == "vCont?":
+                return "vCont;c;C;s;S"
+            if packet.startswith("vCont;"):
+                return "W00"
+            return ""
+
+    def test_continue_no_multiprocess(self):
+        class MyResponder(self.BaseResponder):
+            def qSupported(self, client_supported):
+                return "PacketSize=3fff;QStartNoAckMode+"
+
+            def qfThreadInfo(self):
+                return "m401"
+
+        self.server.responder = MyResponder()
+        self.runCmd("platform select remote-linux")
+        target = self.createTarget("a.yaml")
+        process = self.connect(target)
+        self.assertPacketLogContains(["vCont;C13:401"])
+
+    def test_continue_no_vCont(self):
+        class MyResponder(self.BaseResponder):
+            def qSupported(self, client_supported):
+                return "PacketSize=3fff;QStartNoAckMode+"
+
+            def qfThreadInfo(self):
+                return "m401"
+
+            def other(self, packet):
+                return ""
+
+        self.server.responder = MyResponder()
+        self.runCmd("platform select remote-linux")
+        target = self.createTarget("a.yaml")
+        process = self.connect(target)
+        self.assertPacketLogContains(["Hc401", "C13"])
+
+    def test_continue_multiprocess(self):
+        class MyResponder(self.BaseResponder):
+            pass
+
+        self.server.responder = MyResponder()
+        self.runCmd("platform select remote-linux")
+        target = self.createTarget("a.yaml")
+        process = self.connect(target)
+        self.assertPacketLogContains(["vCont;C13:p400.401"])
+
+    def test_step_multiprocess(self):
+        class MyResponder(self.BaseResponder):
+            def other(self, packet):
+                if packet == "vCont?":
+                    return "vCont;c;C;s;S"
+                if packet.startswith("vCont;C"):
+                    return "S13"
+                if packet.startswith("vCont;s"):
+                    return "W00"
+                return ""
+
+        self.server.responder = MyResponder()
+        self.runCmd("platform select remote-linux")
+        target = self.createTarget("a.yaml")
+        process = self.connect(target)
+        thread = process.GetSelectedThread()
+        thread.StepInstruction(False)
+        self.assertPacketLogContains(["vCont;s:p400.401"])


        


More information about the lldb-commits mailing list