This revision was automatically updated to reflect the committed changes.
Closed by commit rG75757c86c695: [lldb] [llgs] Support multiprocess in
qfThreadInfo (authored by mgorny).
Herald added a project: LLDB.
Repository:
rG LLVM Github Monorepo
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
@@ -1974,38 +1974,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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits