This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
mgorny marked an inline comment as done.
Closed by commit rGf8603c1f6d9e: [lldb] [llgs] Support resuming multiple 
processes via vCont w/ nonstop (authored by mgorny).
Herald added a project: LLDB.

Changed prior to commit:
  https://reviews.llvm.org/D128989?vs=441674&id=449053#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128989/new/

https://reviews.llvm.org/D128989

Files:
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
  lldb/test/API/tools/lldb-server/TestGdbRemoteForkNonStop.py

Index: lldb/test/API/tools/lldb-server/TestGdbRemoteForkNonStop.py
===================================================================
--- lldb/test/API/tools/lldb-server/TestGdbRemoteForkNonStop.py
+++ lldb/test/API/tools/lldb-server/TestGdbRemoteForkNonStop.py
@@ -150,3 +150,55 @@
         self.assertEqual(output.count(b"PID: "), 2)
         self.assertIn("PID: {}".format(int(parent_pid, 16)).encode(), output)
         self.assertIn("PID: {}".format(int(child_pid, 16)).encode(), output)
+
+    @add_test_categories(["fork"])
+    def test_vCont_both_nonstop(self):
+        lock1 = self.getBuildArtifact("lock1")
+        lock2 = self.getBuildArtifact("lock2")
+        parent_pid, parent_tid, child_pid, child_tid = (
+            self.start_fork_test(["fork", "process:sync:" + lock1, "print-pid",
+                                  "process:sync:" + lock2, "stop"],
+                                 nonstop=True))
+
+        self.test_sequence.add_log_lines([
+            "read packet: $vCont;c:p{}.{};c:p{}.{}#00".format(
+                parent_pid, parent_tid, child_pid, child_tid),
+            "send packet: $OK#00",
+            {"direction": "send", "regex": "%Stop:T.*"},
+            ], True)
+        self.expect_gdbremote_sequence()
+
+        output = self.get_all_output_via_vStdio(
+            lambda output: output.count(b"PID: ") >= 2)
+        self.assertEqual(output.count(b"PID: "), 2)
+        self.assertIn("PID: {}".format(int(parent_pid, 16)).encode(), output)
+        self.assertIn("PID: {}".format(int(child_pid, 16)).encode(), output)
+
+    def vCont_both_nonstop_test(self, vCont_packet):
+        lock1 = self.getBuildArtifact("lock1")
+        lock2 = self.getBuildArtifact("lock2")
+        parent_pid, parent_tid, child_pid, child_tid = (
+            self.start_fork_test(["fork", "process:sync:" + lock1, "print-pid",
+                                  "process:sync:" + lock2, "stop"],
+                                 nonstop=True))
+
+        self.test_sequence.add_log_lines([
+            "read packet: ${}#00".format(vCont_packet),
+            "send packet: $OK#00",
+            {"direction": "send", "regex": "%Stop:T.*"},
+            ], True)
+        self.expect_gdbremote_sequence()
+
+        output = self.get_all_output_via_vStdio(
+            lambda output: output.count(b"PID: ") >= 2)
+        self.assertEqual(output.count(b"PID: "), 2)
+        self.assertIn("PID: {}".format(int(parent_pid, 16)).encode(), output)
+        self.assertIn("PID: {}".format(int(child_pid, 16)).encode(), output)
+
+    @add_test_categories(["fork"])
+    def test_vCont_both_implicit_nonstop(self):
+        self.vCont_both_nonstop_test("vCont;c")
+
+    @add_test_categories(["fork"])
+    def test_vCont_both_minus_one_nonstop(self):
+        self.vCont_both_nonstop_test("vCont;c:p-1.-1")
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -1762,6 +1762,7 @@
       break;
     }
 
+    // If there's no thread-id (e.g. "vCont;c"), it's "p-1.-1".
     lldb::pid_t pid = StringExtractorGDBRemote::AllProcesses;
     lldb::tid_t tid = StringExtractorGDBRemote::AllThreads;
 
@@ -1770,7 +1771,7 @@
       // Consume the separator.
       packet.GetChar();
 
-      auto pid_tid = packet.GetPidTid(StringExtractorGDBRemote::AllProcesses);
+      auto pid_tid = packet.GetPidTid(LLDB_INVALID_PROCESS_ID);
       if (!pid_tid)
         return SendIllFormedResponse(packet, "Malformed thread-id");
 
@@ -1784,29 +1785,35 @@
           packet, "'t' action not supported for individual threads");
     }
 
-    if (pid == StringExtractorGDBRemote::AllProcesses) {
-      if (m_debugged_processes.size() > 1)
-        return SendIllFormedResponse(
-            packet, "Resuming multiple processes not supported yet");
+    // If we get TID without PID, it's the current process.
+    if (pid == LLDB_INVALID_PROCESS_ID) {
       if (!m_continue_process) {
-        LLDB_LOG(log, "no debugged process");
+        LLDB_LOG(log, "no process selected via Hc");
         return SendErrorResponse(0x36);
       }
       pid = m_continue_process->GetID();
     }
 
+    assert(pid != LLDB_INVALID_PROCESS_ID);
     if (tid == StringExtractorGDBRemote::AllThreads)
       tid = LLDB_INVALID_THREAD_ID;
-
     thread_action.tid = tid;
 
-    thread_actions[pid].Append(thread_action);
+    if (pid == StringExtractorGDBRemote::AllProcesses) {
+      if (tid != LLDB_INVALID_THREAD_ID)
+        return SendIllFormedResponse(
+            packet, "vCont: p-1 is not valid with a specific tid");
+      for (auto &process_it : m_debugged_processes)
+        thread_actions[process_it.first].Append(thread_action);
+    } else
+      thread_actions[pid].Append(thread_action);
   }
 
   assert(thread_actions.size() >= 1);
-  if (thread_actions.size() > 1)
+  if (thread_actions.size() > 1 && !m_non_stop)
     return SendIllFormedResponse(
-        packet, "Resuming multiple processes not supported yet");
+        packet,
+        "Resuming multiple processes is supported in non-stop mode only");
 
   for (std::pair<lldb::pid_t, ResumeActionList> x : thread_actions) {
     auto process_it = m_debugged_processes.find(x.first);
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to