mgorny updated this revision to Diff 438643.
mgorny added a comment.

Updated to delay removing the process (and therefore stopping lldb-server) 
until the last process exits.


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

https://reviews.llvm.org/D127500

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

Index: lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py
===================================================================
--- lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py
+++ lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py
@@ -262,3 +262,37 @@
             "send packet: $Eff#00",
         ], True)
         self.expect_gdbremote_sequence()
+
+    @add_test_categories(["fork"])
+    def test_kill_all(self):
+        self.build()
+        self.prep_debug_monitor_and_inferior(inferior_args=["fork"])
+        self.add_qSupported_packets(["multiprocess+",
+                                     "fork-events+"])
+        ret = self.expect_gdbremote_sequence()
+        self.assertIn("fork-events+", ret["qSupported_response"])
+        self.reset_test_sequence()
+
+        # continue and expect fork
+        self.test_sequence.add_log_lines([
+            "read packet: $c#00",
+            {"direction": "send", "regex": self.fork_regex.format("fork"),
+             "capture": self.fork_capture},
+        ], True)
+        ret = self.expect_gdbremote_sequence()
+        parent_pid = ret["parent_pid"]
+        child_pid = ret["child_pid"]
+        self.reset_test_sequence()
+
+        exit_regex = "[$]X09;process:([0-9a-f]+)#.*"
+        self.test_sequence.add_log_lines([
+            # kill all processes
+            "read packet: $k#00",
+            {"direction": "send", "regex": exit_regex,
+             "capture": {1: "pid1"}},
+            {"direction": "send", "regex": exit_regex,
+             "capture": {1: "pid2"}},
+        ], True)
+        ret = self.expect_gdbremote_sequence()
+        self.assertEqual(set([ret["pid1"], ret["pid2"]]),
+                         set([parent_pid, child_pid]))
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
@@ -992,13 +992,24 @@
               __FUNCTION__, process->GetID());
   }
 
-  // Close the pipe to the inferior terminal i/o if we launched it and set one
-  // up.
-  MaybeCloseInferiorTerminalConnection();
-
-  // We are ready to exit the debug monitor.
-  m_exit_now = true;
-  m_mainloop.RequestTermination();
+  if (m_current_process == process)
+    m_current_process = nullptr;
+  if (m_continue_process == process)
+    m_continue_process = nullptr;
+
+  lldb::pid_t pid = process->GetID();
+  m_mainloop.AddPendingCallback([&, pid](MainLoopBase &loop) {
+    m_debugged_processes.erase(pid);
+    if (m_debugged_processes.empty()) {
+      // Close the pipe to the inferior terminal i/o if we launched it and set
+      // one up.
+      MaybeCloseInferiorTerminalConnection();
+
+      // We are ready to exit the debug monitor.
+      m_exit_now = true;
+      loop.RequestTermination();
+    }
+  });
 }
 
 void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped(
@@ -1161,12 +1172,19 @@
 }
 
 void GDBRemoteCommunicationServerLLGS::StartSTDIOForwarding() {
+  Log *log = GetLog(LLDBLog::Process);
+
   // Don't forward if not connected (e.g. when attaching).
   if (!m_stdio_communication.IsConnected())
     return;
 
+  // If we're not debugging multiple processes, this should be called
+  // once.
+  if (!bool(m_extensions_supported &
+            NativeProcessProtocol::Extension::multiprocess))
+    assert(!m_stdio_handle_up);
+
   Status error;
-  lldbassert(!m_stdio_handle_up);
   m_stdio_handle_up = m_mainloop.RegisterReadObject(
       m_stdio_communication.GetConnection()->GetReadObject(),
       [this](MainLoopBase &) { SendProcessOutput(); }, error);
@@ -1174,15 +1192,27 @@
   if (!m_stdio_handle_up) {
     // Not much we can do about the failure. Log it and continue without
     // forwarding.
-    if (Log *log = GetLog(LLDBLog::Process))
-      LLDB_LOGF(log,
-                "GDBRemoteCommunicationServerLLGS::%s Failed to set up stdio "
-                "forwarding: %s",
-                __FUNCTION__, error.AsCString());
+    LLDB_LOG(log, "Failed to set up stdio forwarding: {0}", error);
   }
 }
 
 void GDBRemoteCommunicationServerLLGS::StopSTDIOForwarding() {
+  Log *log = GetLog(LLDBLog::Process);
+
+  if (bool(m_extensions_supported &
+           NativeProcessProtocol::Extension::multiprocess)) {
+    // Leave stdio forwarding open if there's at least one running process
+    // still.
+    for (auto &x : m_debugged_processes) {
+      if (x.second->IsRunning()) {
+        LLDB_LOG(log,
+                 "process {0} is still running, stdio forwarding stays open",
+                 x.first);
+        return;
+      }
+    }
+  }
+
   m_stdio_handle_up.reset();
 }
 
@@ -1363,15 +1393,19 @@
 
   StopSTDIOForwarding();
 
-  if (!m_current_process) {
+  if (m_debugged_processes.empty()) {
     LLDB_LOG(log, "No debugged process found.");
     return PacketResult::Success;
   }
 
-  Status error = m_current_process->Kill();
-  if (error.Fail())
-    LLDB_LOG(log, "Failed to kill debugged process {0}: {1}",
-             m_current_process->GetID(), error);
+  for (auto it = m_debugged_processes.begin(); it != m_debugged_processes.end();
+       ++it) {
+    LLDB_LOG(log, "Killing process {0}", it->first);
+    Status error = it->second->Kill();
+    if (error.Fail())
+      LLDB_LOG(log, "Failed to kill debugged process {0}: {1}", it->first,
+               error);
+  }
 
   // No OK response for kill packet.
   // return SendOKResponse ();
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to