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