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( 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"])