mgorny created this revision.
mgorny added reviewers: labath, jingham, krytarowski, emaste.
Herald added a subscriber: arichardson.
Herald added a project: All.
mgorny requested review of this revision.

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


https://reviews.llvm.org/D131758

Files:
  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/test/API/functionalities/gdb_remote_client/TestContinue.py

Index: lldb/test/API/functionalities/gdb_remote_client/TestContinue.py
===================================================================
--- /dev/null
+++ 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"])
Index: lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -1186,11 +1186,16 @@
     StreamString continue_packet;
     bool continue_packet_error = false;
     if (m_gdb_comm.HasAnyVContSupport()) {
+      std::string pid_prefix;
+      if (GetID() != LLDB_INVALID_PROCESS_ID &&
+          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 +1205,7 @@
                      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 +1216,8 @@
                      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 +1228,7 @@
                      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 +1239,8 @@
                      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;
         }
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -339,6 +339,8 @@
 
   bool GetQXferSigInfoReadSupported();
 
+  bool GetMultiprocessSupported();
+
   LazyBool SupportsAllocDeallocMemory() // const
   {
     // Uncomment this to have lldb pretend the debug server doesn't respond to
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -181,6 +181,12 @@
   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 @@
     }
   }
 
-  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)
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to