[Lldb-commits] [lldb] c732afa - [lldb] [llgs] Fix disabling non-stop mode

Michał Górny via lldb-commits lldb-commits at lists.llvm.org
Fri Jul 15 11:17:15 PDT 2022


Author: Michał Górny
Date: 2022-07-15T20:16:49+02:00
New Revision: c732afa2c2e8bf4c3d068af180c1e9daa25b03c1

URL: https://github.com/llvm/llvm-project/commit/c732afa2c2e8bf4c3d068af180c1e9daa25b03c1
DIFF: https://github.com/llvm/llvm-project/commit/c732afa2c2e8bf4c3d068af180c1e9daa25b03c1.diff

LOG: [lldb] [llgs] Fix disabling non-stop mode

Stop all processes and clear notification queues when disabling non-stop
mode.  Ensure that no stop notifications are sent for processes stopped
due to the mode switch.

Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.llvm.org/D128893

Added: 
    

Modified: 
    lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
    lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
    lldb/test/API/tools/lldb-server/TestNonStop.py

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index 1bc94658f1958..be789bdf7da50 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -1919,6 +1919,20 @@ GDBRemoteCommunicationServerLLGS::SendStopReasonForState(
     bool force_synchronous) {
   Log *log = GetLog(LLDBLog::Process);
 
+  if (m_disabling_non_stop) {
+    // Check if we are waiting for any more processes to stop.  If we are,
+    // do not send the OK response yet.
+    for (const auto &it : m_debugged_processes) {
+      if (it.second.process_up->IsRunning())
+        return PacketResult::Success;
+    }
+
+    // If all expected processes were stopped after a QNonStop:0 request,
+    // send the OK response.
+    m_disabling_non_stop = false;
+    return SendOKResponse();
+  }
+
   switch (process_state) {
   case eStateAttaching:
   case eStateLaunching:
@@ -3903,12 +3917,33 @@ GDBRemoteCommunicationServerLLGS::Handle_qSaveCore(
 GDBRemoteCommunication::PacketResult
 GDBRemoteCommunicationServerLLGS::Handle_QNonStop(
     StringExtractorGDBRemote &packet) {
+  Log *log = GetLog(LLDBLog::Process);
+
   StringRef packet_str{packet.GetStringRef()};
   assert(packet_str.startswith("QNonStop:"));
   packet_str.consume_front("QNonStop:");
   if (packet_str == "0") {
+    for (auto &process_it : m_debugged_processes) {
+      if (process_it.second.process_up->IsRunning()) {
+        assert(m_non_stop);
+        Status error = process_it.second.process_up->Interrupt();
+        if (error.Fail()) {
+          LLDB_LOG(log,
+                   "while disabling nonstop, failed to halt process {0}: {1}",
+                   process_it.first, error);
+          return SendErrorResponse(0x41);
+        }
+        // we must not send stop reasons after QNonStop
+        m_disabling_non_stop = true;
+      }
+    }
+    m_stdio_notification_queue.clear();
+    m_stop_notification_queue.clear();
     m_non_stop = false;
-    // TODO: stop all threads
+    // If we are stopping anything, defer sending the OK response until we're
+    // done.
+    if (m_disabling_non_stop)
+      return PacketResult::Success;
   } else if (packet_str == "1") {
     m_non_stop = true;
   } else

diff  --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
index 3d67032fc62d6..1165b60ac762b 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -117,6 +117,7 @@ class GDBRemoteCommunicationServerLLGS
   bool m_thread_suffix_supported = false;
   bool m_list_threads_in_stop_reply = false;
   bool m_non_stop = false;
+  bool m_disabling_non_stop = false;
   std::deque<std::string> m_stdio_notification_queue;
   std::deque<std::string> m_stop_notification_queue;
 

diff  --git a/lldb/test/API/tools/lldb-server/TestNonStop.py b/lldb/test/API/tools/lldb-server/TestNonStop.py
index 5f08aae0f2dbb..13cfe7ad3c6be 100644
--- a/lldb/test/API/tools/lldb-server/TestNonStop.py
+++ b/lldb/test/API/tools/lldb-server/TestNonStop.py
@@ -362,3 +362,33 @@ def test_stop_reason_while_running(self):
              "send packet: $OK#00",
              ], True)
         self.expect_gdbremote_sequence()
+
+    @add_test_categories(["llgs"])
+    def test_leave_nonstop(self):
+        self.build()
+        self.set_inferior_startup_launch()
+        procs = self.prep_debug_monitor_and_inferior(
+                inferior_args=["thread:new", "thread:new", "stop", "sleep:15"])
+        self.test_sequence.add_log_lines(
+            ["read packet: $QNonStop:1#00",
+             "send packet: $OK#00",
+             # stop is used to synchronize starting threads
+             "read packet: $c#63",
+             "send packet: $OK#00",
+             {"direction": "send", "regex": "%Stop:T.*"},
+             "read packet: $c#63",
+             "send packet: $OK#00",
+             # verify that the threads are running now
+             "read packet: $?#00",
+             "send packet: $OK#00",
+             "read packet: $QNonStop:0#00",
+             "send packet: $OK#00",
+             # we should issue some random request now to verify that the stub
+             # did not send stop reasons -- we may verify whether notification
+             # queue was cleared while at it
+             "read packet: $vStopped#00",
+             "send packet: $Eff#00",
+             "read packet: $?#00",
+             {"direction": "send", "regex": "[$]T.*"},
+             ], True)
+        self.expect_gdbremote_sequence()


        


More information about the lldb-commits mailing list