Reland "[lldb] [llgs] Support multiprocess in qfThreadInfo"
authorMichał Górny <mgorny@moritz.systems>
Sat, 25 Jun 2022 13:04:26 +0000 (15:04 +0200)
committerMichał Górny <mgorny@moritz.systems>
Sat, 25 Jun 2022 13:15:37 +0000 (15:15 +0200)
Now preserving the non-standard behavior of returning "OK" response
when there is no debugged process.

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

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

index 770edbf..2c009ef 100644 (file)
@@ -1976,38 +1976,43 @@ GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo(
   return SendPacketNoLock(response.GetString());
 }
 
-GDBRemoteCommunication::PacketResult
-GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo(
-    StringExtractorGDBRemote &packet) {
+void GDBRemoteCommunicationServerLLGS::AddProcessThreads(
+    StreamGDBRemote &response, NativeProcessProtocol &process, bool &had_any) {
   Log *log = GetLog(LLDBLog::Thread);
 
-  // Fail if we don't have a current process.
-  if (!m_current_process ||
-      (m_current_process->GetID() == LLDB_INVALID_PROCESS_ID)) {
-    LLDB_LOG(log, "no process ({0}), returning OK",
-             m_current_process ? "invalid process id"
-                               : "null m_current_process");
-    return SendOKResponse();
-  }
-
-  StreamGDBRemote response;
-  response.PutChar('m');
+  lldb::pid_t pid = process.GetID();
+  if (pid == LLDB_INVALID_PROCESS_ID)
+    return;
 
-  LLDB_LOG(log, "starting thread iteration");
+  LLDB_LOG(log, "iterating over threads of process {0}", process.GetID());
   NativeThreadProtocol *thread;
   uint32_t thread_index;
-  for (thread_index = 0,
-      thread = m_current_process->GetThreadAtIndex(thread_index);
-       thread; ++thread_index,
-      thread = m_current_process->GetThreadAtIndex(thread_index)) {
-    LLDB_LOG(log, "iterated thread {0}(tid={2})", thread_index,
+  for (thread_index = 0, thread = process.GetThreadAtIndex(thread_index);
+       thread;
+       ++thread_index, thread = process.GetThreadAtIndex(thread_index)) {
+    LLDB_LOG(log, "iterated thread {0} (tid={1})", thread_index,
              thread->GetID());
-    if (thread_index > 0)
-      response.PutChar(',');
-    response.Printf("%" PRIx64, thread->GetID());
+    response.PutChar(had_any ? ',' : 'm');
+    AppendThreadIDToResponse(response, pid, thread->GetID());
+    had_any = true;
   }
+}
 
-  LLDB_LOG(log, "finished thread iteration");
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo(
+    StringExtractorGDBRemote &packet) {
+  assert(m_debugged_processes.size() == 1 ||
+         bool(m_extensions_supported &
+              NativeProcessProtocol::Extension::multiprocess));
+
+  bool had_any = false;
+  StreamGDBRemote response;
+
+  for (auto &pid_ptr : m_debugged_processes)
+    AddProcessThreads(response, *pid_ptr.second, had_any);
+
+  if (!had_any)
+    return SendOKResponse();
   return SendPacketNoLock(response.GetString());
 }
 
index 17cc321..5187a95 100644 (file)
@@ -159,6 +159,9 @@ protected:
 
   PacketResult Handle_qRegisterInfo(StringExtractorGDBRemote &packet);
 
+  void AddProcessThreads(StreamGDBRemote &response,
+                         NativeProcessProtocol &process, bool &had_any);
+
   PacketResult Handle_qfThreadInfo(StringExtractorGDBRemote &packet);
 
   PacketResult Handle_qsThreadInfo(StringExtractorGDBRemote &packet);
index b60481a..d8c93b8 100644 (file)
@@ -396,7 +396,6 @@ class TestGdbRemoteFork(gdbremote_testcase.GdbRemoteTestCaseBase):
         self.expect_gdbremote_sequence()
 
     @add_test_categories(["fork"])
-    @expectedFailureAll()  # qfThreadInfo changes temporarily reverted
     def test_threadinfo(self):
         parent_pid, parent_tid, child_pid, child_tid = (
             self.start_fork_test(["fork", "thread:new", "trap"]))
@@ -529,7 +528,6 @@ class TestGdbRemoteFork(gdbremote_testcase.GdbRemoteTestCaseBase):
             self.reset_test_sequence()
 
     @add_test_categories(["fork"])
-    @expectedFailureAll()  # qfThreadInfo changes temporarily reverted
     def test_register_read_write(self):
         parent_pid, parent_tid, child_pid, child_tid = (
             self.start_fork_test(["fork", "thread:new", "trap"]))
@@ -626,7 +624,6 @@ class TestGdbRemoteFork(gdbremote_testcase.GdbRemoteTestCaseBase):
             self.assertEqual(data, old_val[1])
 
     @add_test_categories(["fork"])
-    @expectedFailureAll()  # qfThreadInfo changes temporarily reverted
     def test_qC(self):
         parent_pid, parent_tid, child_pid, child_tid = (
             self.start_fork_test(["fork", "thread:new", "trap"]))
@@ -661,7 +658,6 @@ class TestGdbRemoteFork(gdbremote_testcase.GdbRemoteTestCaseBase):
         self.expect_gdbremote_sequence()
 
     @add_test_categories(["fork"])
-    @expectedFailureAll()  # qfThreadInfo changes temporarily reverted
     def test_T(self):
         parent_pid, parent_tid, child_pid, child_tid = (
             self.start_fork_test(["fork", "thread:new", "trap"]))