[Lldb-commits] [lldb] e827e51 - [lldb] [llgs] Implement the 'T' packet

Michał Górny via lldb-commits lldb-commits at lists.llvm.org
Fri Jun 24 08:20:47 PDT 2022


Author: Michał Górny
Date: 2022-06-24T17:20:24+02:00
New Revision: e827e5186fb6991bc749eaaddf13f8a53ebb63c2

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

LOG: [lldb] [llgs] Implement the 'T' packet

Implement the 'T' packet that is used to verify whether the specified
thread belongs to the debugged processes.

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

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index 18712cf5b323b..f5c66496d7659 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -107,6 +107,8 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() {
                                 &GDBRemoteCommunicationServerLLGS::Handle_P);
   RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qC,
                                 &GDBRemoteCommunicationServerLLGS::Handle_qC);
+  RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_T,
+                                &GDBRemoteCommunicationServerLLGS::Handle_T);
   RegisterMemberFunctionHandler(
       StringExtractorGDBRemote::eServerPacketType_qfThreadInfo,
       &GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo);
@@ -3898,6 +3900,36 @@ GDBRemoteCommunicationServerLLGS::Handle_vCtrlC(
   return SendOKResponse();
 }
 
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_T(StringExtractorGDBRemote &packet) {
+  packet.SetFilePos(strlen("T"));
+  auto pid_tid = packet.GetPidTid(m_current_process ? m_current_process->GetID()
+                                                    : LLDB_INVALID_PROCESS_ID);
+  if (!pid_tid)
+    return SendErrorResponse(llvm::make_error<StringError>(
+        inconvertibleErrorCode(), "Malformed thread-id"));
+
+  lldb::pid_t pid = pid_tid->first;
+  lldb::tid_t tid = pid_tid->second;
+
+  // Technically, this would also be caught by the PID check but let's be more
+  // explicit about the error.
+  if (pid == LLDB_INVALID_PROCESS_ID)
+    return SendErrorResponse(llvm::make_error<StringError>(
+        inconvertibleErrorCode(), "No current process and no PID provided"));
+
+  // Check the process ID and find respective process instance.
+  auto new_process_it = m_debugged_processes.find(pid);
+  if (new_process_it == m_debugged_processes.end())
+    return SendErrorResponse(1);
+
+  // Check the thread ID
+  if (!new_process_it->second->GetThreadByID(tid))
+    return SendErrorResponse(2);
+
+  return SendOKResponse();
+}
+
 void GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection() {
   Log *log = GetLog(LLDBLog::Process);
 

diff  --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
index 03a548b076e46..abb7f10f4830f 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -246,6 +246,8 @@ class GDBRemoteCommunicationServerLLGS
 
   PacketResult Handle_QMemTags(StringExtractorGDBRemote &packet);
 
+  PacketResult Handle_T(StringExtractorGDBRemote &packet);
+
   void SetCurrentThreadID(lldb::tid_t tid);
 
   lldb::tid_t GetCurrentThreadID() const;

diff  --git a/lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py b/lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py
index fdd9e94d0a364..23e387afd4cd4 100644
--- a/lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py
+++ b/lldb/test/API/tools/lldb-server/TestGdbRemoteFork.py
@@ -866,3 +866,76 @@ def test_qC(self):
                  "send packet: $QCp{:x}.{:x}#00".format(*pidtid),
                  ], True)
         self.expect_gdbremote_sequence()
+
+    @add_test_categories(["fork"])
+    def test_T(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"]),
+        ]
+        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()
+
+        pidtids = set(self.parse_threadinfo_packets(ret))
+        self.assertEqual(len(pidtids), 4)
+        max_pid = max(pid for pid, tid in pidtids)
+        max_tid = max(tid for pid, tid in pidtids)
+        bad_pidtids = (
+            (max_pid, max_tid + 1, "E02"),
+            (max_pid + 1, max_tid, "E01"),
+            (max_pid + 1, max_tid + 1, "E01"),
+        )
+
+        for pidtid in pidtids:
+            self.test_sequence.add_log_lines(
+                [
+                 # test explicit PID+TID
+                 "read packet: $Tp{:x}.{:x}#00".format(*pidtid),
+                 "send packet: $OK#00",
+                 # test implicit PID via Hg
+                 "read packet: $Hgp{:x}.{:x}#00".format(*pidtid),
+                 "send packet: $OK#00",
+                 "read packet: $T{:x}#00".format(max_tid + 1),
+                 "send packet: $E02#00",
+                 "read packet: $T{:x}#00".format(pidtid[1]),
+                 "send packet: $OK#00",
+                 ], True)
+        for pid, tid, expected in bad_pidtids:
+            self.test_sequence.add_log_lines(
+                ["read packet: $Tp{:x}.{:x}#00".format(pid, tid),
+                 "send packet: ${}#00".format(expected),
+                 ], True)
+        self.expect_gdbremote_sequence()


        


More information about the lldb-commits mailing list