mgorny updated this revision to Diff 438914.
mgorny marked an inline comment as done.
mgorny added a comment.

Simplify to use a single loop for both multiprocess and non-multiprocess modes. 
Replace the static function with `include_pid` with a class method, to prepare 
for adding a new helper to print PID+TID.


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

https://reviews.llvm.org/D128152

Files:
  lldb/packages/Python/lldbsuite/test/tools/lldb-server/lldbgdbserverutils.py
  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: lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py
===================================================================
--- lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py
+++ lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py
@@ -554,6 +554,66 @@
         ], True)
         self.expect_gdbremote_sequence()
 
+    @add_test_categories(["fork"])
+    def test_threadinfo(self):
+        self.build()
+        self.prep_debug_monitor_and_inferior(
+            inferior_args=["fork",
+                           "thread:new",
+                           "trap",
+                           ])
+        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)
+        self.add_threadinfo_collection_packets()
+        ret = self.expect_gdbremote_sequence()
+        pidtids = [
+            (ret["parent_pid"], ret["parent_tid"]),
+            (ret["child_pid"], ret["child_tid"]),
+        ]
+        prev_pidtids = set(self.parse_threadinfo_packets(ret))
+        self.assertEqual(prev_pidtids,
+                         frozenset((int(pid, 16), int(tid, 16))
+                                   for pid, tid in pidtids))
+        self.reset_test_sequence()
+
+        for pidtid in pidtids:
+            self.test_sequence.add_log_lines(
+                ["read packet: $Hcp{}.{}#00".format(*pidtid),
+                 "send packet: $OK#00",
+                 "read packet: $c#00",
+                 {"direction": "send",
+                  "regex": "^[$]T05thread:p{}.{}.*".format(*pidtid),
+                  },
+                 ], True)
+            self.add_threadinfo_collection_packets()
+            ret = self.expect_gdbremote_sequence()
+            self.reset_test_sequence()
+            new_pidtids = set(self.parse_threadinfo_packets(ret))
+            added_pidtid = new_pidtids - prev_pidtids
+            prev_pidtids = new_pidtids
+
+            # verify that we've got exactly one new thread, and that
+            # the PID matches
+            self.assertEqual(len(added_pidtid), 1)
+            self.assertEqual(added_pidtid.pop()[0], int(pidtid[0], 16))
+
+        for pidtid in new_pidtids:
+            self.test_sequence.add_log_lines(
+                ["read packet: $Hgp{:x}.{:x}#00".format(*pidtid),
+                 "send packet: $OK#00",
+                 ], True)
+        self.expect_gdbremote_sequence()
+
     @add_test_categories(["fork"])
     def test_memory_read_write(self):
         self.build()
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -159,6 +159,9 @@
 
   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: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
===================================================================
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -1997,38 +1997,46 @@
   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');
+    if (bool(m_extensions_supported &
+             NativeProcessProtocol::Extension::multiprocess))
+      response.Format("p{0:x-}.", pid);
+    response.Format("{0:x-}", 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)
+    response.PutChar('l');
   return SendPacketNoLock(response.GetString());
 }
 
Index: lldb/packages/Python/lldbsuite/test/tools/lldb-server/lldbgdbserverutils.py
===================================================================
--- lldb/packages/Python/lldbsuite/test/tools/lldb-server/lldbgdbserverutils.py
+++ lldb/packages/Python/lldbsuite/test/tools/lldb-server/lldbgdbserverutils.py
@@ -284,9 +284,14 @@
     response_packet = _STRIP_COMMAND_PREFIX_M_REGEX.sub("", response_packet)
     response_packet = _STRIP_CHECKSUM_REGEX.sub("", response_packet)
 
-    # Return list of thread ids
-    return [int(thread_id_hex, 16) for thread_id_hex in response_packet.split(
-        ",") if len(thread_id_hex) > 0]
+    for tid in response_packet.split(","):
+        if not tid:
+            continue
+        if tid.startswith("p"):
+            pid, _, tid = tid.partition(".")
+            yield (int(pid[1:], 16), int(tid, 16))
+        else:
+            yield int(tid, 16)
 
 
 def unpack_endian_binary_string(endian, value_string):
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to