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

Enable stdio forwarding when nonstop mode is enabled, and disable it
once it is disabled.  This makes it possible to cleanly handle stdio
forwarding while running multiple processes in non-stop mode.

Sponsored by: The FreeBSD Foundation


https://reviews.llvm.org/D128932

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
@@ -1,3 +1,5 @@
+import binascii
+
 from lldbsuite.test.decorators import *
 from lldbsuite.test.lldbtest import *
 
@@ -107,3 +109,31 @@
     def test_vCont_interspersed_nonstop(self):
         self.resume_one_test(run_order=["parent", "child", "parent", "child"],
                              use_vCont=True, nonstop=True)
+
+    @add_test_categories(["fork"])
+    def test_c_both_nonstop(self):
+        parent_pid, parent_tid, child_pid, child_tid = (
+            self.start_fork_test(["fork", "sleep:2", "print-pid", "sleep:2",
+                                  "stop"],
+                                 nonstop=True))
+
+        self.test_sequence.add_log_lines([
+            "read packet: $Hcp{}.{}#00".format(parent_pid, parent_tid),
+            "send packet: $OK#00",
+            "read packet: $c#00",
+            "send packet: $OK#00",
+            "read packet: $Hcp{}.{}#00".format(child_pid, child_tid),
+            "send packet: $OK#00",
+            "read packet: $c#00",
+            "send packet: $OK#00",
+            {"direction": "send", "regex": "%Stop:T.*"},
+            # see the comment in TestNonStop.py, test_stdio
+            "read packet: $vStdio#00",
+            "read packet: $vStdio#00",
+            "send packet: $OK#00",
+            ], True)
+        ret = self.expect_gdbremote_sequence()
+        self.assertIn("PID: {}".format(int(parent_pid, 16)).encode(),
+                      ret["O_content"])
+        self.assertIn("PID: {}".format(int(child_pid, 16)).encode(),
+                      ret["O_content"])
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
@@ -1107,14 +1107,16 @@
     SendProcessOutput();
     // Then stop the forwarding, so that any late output (see llvm.org/pr25652)
     // does not interfere with our protocol.
-    StopSTDIOForwarding();
+    if (!m_non_stop)
+      StopSTDIOForwarding();
     HandleInferiorState_Stopped(process);
     break;
 
   case StateType::eStateExited:
     // Same as above
     SendProcessOutput();
-    StopSTDIOForwarding();
+    if (!m_non_stop)
+      StopSTDIOForwarding();
     HandleInferiorState_Exited(process);
     break;
 
@@ -1417,7 +1419,8 @@
 GDBRemoteCommunicationServerLLGS::Handle_k(StringExtractorGDBRemote &packet) {
   Log *log = GetLog(LLDBLog::Process);
 
-  StopSTDIOForwarding();
+  if (!m_non_stop)
+    StopSTDIOForwarding();
 
   if (m_debugged_processes.empty()) {
     LLDB_LOG(log, "No debugged process found.");
@@ -1443,7 +1446,8 @@
 GDBRemoteCommunication::PacketResult
 GDBRemoteCommunicationServerLLGS::Handle_vKill(
     StringExtractorGDBRemote &packet) {
-  StopSTDIOForwarding();
+  if (!m_non_stop)
+    StopSTDIOForwarding();
 
   packet.SetFilePos(6); // vKill;
   uint32_t pid = packet.GetU32(LLDB_INVALID_PROCESS_ID, 16);
@@ -3519,7 +3523,8 @@
 GDBRemoteCommunication::PacketResult
 GDBRemoteCommunicationServerLLGS::Handle_D(StringExtractorGDBRemote &packet) {
   Log *log = GetLog(LLDBLog::Process);
-  StopSTDIOForwarding();
+  if (!m_non_stop)
+    StopSTDIOForwarding();
 
   lldb::pid_t pid = LLDB_INVALID_PROCESS_ID;
 
@@ -3918,6 +3923,8 @@
   assert(packet_str.startswith("QNonStop:"));
   packet_str.consume_front("QNonStop:");
   if (packet_str == "0") {
+    if (m_non_stop)
+      StopSTDIOForwarding();
     for (const auto &process_it : m_debugged_processes) {
       if (process_it.second->IsRunning()) {
         Status error = process_it.second->Interrupt();
@@ -3935,6 +3942,8 @@
     m_stop_notification_queue.clear();
     m_non_stop = false;
   } else if (packet_str == "1") {
+    if (!m_non_stop)
+      StartSTDIOForwarding();
     m_non_stop = true;
   } else
     return SendErrorResponse(Status("Invalid QNonStop packet"));
@@ -4228,9 +4237,10 @@
 
 GDBRemoteCommunication::PacketResult
 GDBRemoteCommunicationServerLLGS::SendContinueSuccessResponse() {
-  // TODO: how to handle forwarding in non-stop mode?
+  if (m_non_stop)
+    return SendOKResponse();
   StartSTDIOForwarding();
-  return m_non_stop ? SendOKResponse() : PacketResult::Success;
+  return PacketResult::Success;
 }
 
 void GDBRemoteCommunicationServerLLGS::AppendThreadIDToResponse(
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to