[Lldb-commits] [lldb] r362063 - [lldb-server] Support 'g' packets

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Thu May 30 00:25:22 PDT 2019


Author: labath
Date: Thu May 30 00:25:22 2019
New Revision: 362063

URL: http://llvm.org/viewvc/llvm-project?rev=362063&view=rev
Log:
[lldb-server] Support 'g' packets

Differential Revision: https://reviews.llvm.org/D62221
Patch by Guilherme Andrade <guiandrade at google.com>.

Added:
    lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/register-reading/
    lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/register-reading/Makefile
    lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/register-reading/TestGdbRemoteGPacket.py
    lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/register-reading/main.cpp
Removed:
    lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteGPacket.py
Modified:
    lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py
    lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
    lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp

Removed: lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteGPacket.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteGPacket.py?rev=362062&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteGPacket.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/TestGdbRemoteGPacket.py (removed)
@@ -1,41 +0,0 @@
-from __future__ import print_function
-
-
-import gdbremote_testcase
-from lldbsuite.test.decorators import *
-from lldbsuite.test.lldbtest import *
-from lldbsuite.test import lldbutil
-
-
-class TestGdbRemoteGPacket(gdbremote_testcase.GdbRemoteTestCaseBase):
-
-    mydir = TestBase.compute_mydir(__file__)
-
-    def run_test_g_packet(self):
-        self.build()
-        self.prep_debug_monitor_and_inferior()
-        self.test_sequence.add_log_lines(
-            ["read packet: $g#67",
-             {"direction": "send", "regex": r"^\$(.+)#[0-9a-fA-F]{2}$",
-              "capture": {1: "register_bank"}}],
-            True)
-        self.connect_to_debug_monitor()
-        context = self.expect_gdbremote_sequence()
-        register_bank = context.get("register_bank")
-        self.assertTrue(register_bank[0] != 'E')
-
-        self.test_sequence.add_log_lines(
-            ["read packet: $G" + register_bank + "#00",
-             {"direction": "send", "regex": r"^\$(.+)#[0-9a-fA-F]{2}$",
-              "capture": {1: "G_reply"}}],
-            True)
-        context = self.expect_gdbremote_sequence()
-        self.assertTrue(context.get("G_reply")[0] != 'E')
-
-
-    @skipIfOutOfTreeDebugserver
-    @debugserver_test
-    @skipIfDarwinEmbedded
-    def test_g_packet_debugserver(self):
-        self.init_debugserver_test()
-        self.run_test_g_packet()

Modified: lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py?rev=362063&r1=362062&r2=362063&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py Thu May 30 00:25:22 2019
@@ -558,9 +558,7 @@ class LldbGdbServerTestCase(gdbremote_te
         self.assertIsNotNone(reg_infos)
         self.assertTrue(len(reg_infos) > 0)
 
-        inferior_exe_path = self.getBuildArtifact("a.out")
-        Target = self.dbg.CreateTarget(inferior_exe_path)
-        byte_order = Target.GetByteOrder()
+        byte_order = self.get_target_byte_order()
 
         # Read value for each register.
         reg_index = 0

Modified: lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py?rev=362063&r1=362062&r2=362063&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py Thu May 30 00:25:22 2019
@@ -378,6 +378,11 @@ class GdbRemoteTestCaseBase(TestBase):
             commandline_args += ["--named-pipe", self.named_pipe_path]
         return commandline_args
 
+    def get_target_byte_order(self):
+        inferior_exe_path = self.getBuildArtifact("a.out")
+        target = self.dbg.CreateTarget(inferior_exe_path)
+        return target.GetByteOrder()
+
     def launch_debug_monitor(self, attach_pid=None, logfile=None):
         # Create the command line.
         commandline_args = self.get_debug_monitor_command_line_args(

Added: lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/register-reading/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/register-reading/Makefile?rev=362063&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/register-reading/Makefile (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/register-reading/Makefile Thu May 30 00:25:22 2019
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/register-reading/TestGdbRemoteGPacket.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/register-reading/TestGdbRemoteGPacket.py?rev=362063&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/register-reading/TestGdbRemoteGPacket.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/register-reading/TestGdbRemoteGPacket.py Thu May 30 00:25:22 2019
@@ -0,0 +1,153 @@
+from __future__ import print_function
+
+
+import gdbremote_testcase
+import textwrap
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+def _extract_register_value(reg_info, reg_bank, byte_order, bytes_per_entry=8):
+    reg_offset = int(reg_info["offset"])*2
+    reg_byte_size = int(2 * int(reg_info["bitsize"]) / 8)
+    # Create slice with the contents of the register.
+    reg_slice = reg_bank[reg_offset:reg_offset+reg_byte_size]
+
+    reg_value = []
+    # Wrap slice according to bytes_per_entry.
+    for entry in textwrap.wrap(reg_slice, 2 * bytes_per_entry):
+        # Invert the bytes order if target uses little-endian.
+        if byte_order == lldb.eByteOrderLittle:
+            entry = "".join(reversed([entry[i:i+2] for i in range(0,
+                                          len(entry),2)]))
+        reg_value.append("0x" + entry)
+
+    return reg_value
+
+
+class TestGdbRemoteGPacket(gdbremote_testcase.GdbRemoteTestCaseBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    def run_test_g_packet(self):
+        self.build()
+        self.prep_debug_monitor_and_inferior()
+        self.test_sequence.add_log_lines(
+            ["read packet: $g#67",
+             {"direction": "send", "regex": r"^\$(.+)#[0-9a-fA-F]{2}$",
+              "capture": {1: "register_bank"}}],
+            True)
+        self.connect_to_debug_monitor()
+        context = self.expect_gdbremote_sequence()
+        register_bank = context.get("register_bank")
+        self.assertTrue(register_bank[0] != 'E')
+
+        self.test_sequence.add_log_lines(
+            ["read packet: $G" + register_bank + "#00",
+             {"direction": "send", "regex": r"^\$(.+)#[0-9a-fA-F]{2}$",
+              "capture": {1: "G_reply"}}],
+            True)
+        context = self.expect_gdbremote_sequence()
+        self.assertTrue(context.get("G_reply")[0] != 'E')
+
+    @skipIfOutOfTreeDebugserver
+    @debugserver_test
+    @skipIfDarwinEmbedded
+    def test_g_packet_debugserver(self):
+        self.init_debugserver_test()
+        self.run_test_g_packet()
+
+    @skipIf(archs=no_match(["x86_64"]))
+    def g_returns_correct_data(self, with_suffix):
+        procs = self.prep_debug_monitor_and_inferior()
+
+        self.add_register_info_collection_packets()
+        if with_suffix:
+            self.add_thread_suffix_request_packets()
+        self.add_threadinfo_collection_packets()
+        context = self.expect_gdbremote_sequence()
+        self.assertIsNotNone(context)
+
+        # Gather register info.
+        reg_infos = self.parse_register_info_packets(context)
+        self.assertIsNotNone(reg_infos)
+        self.add_lldb_register_index(reg_infos)
+        # Index register info entries by name.
+        reg_infos = {info['name']: info for info in reg_infos}
+
+        # Gather thread info.
+        if with_suffix:
+            threads = self.parse_threadinfo_packets(context)
+            self.assertIsNotNone(threads)
+            thread_id = threads[0]
+            self.assertIsNotNone(thread_id)
+        else:
+            thread_id = None
+
+        # Send vCont packet to resume the inferior.
+        self.test_sequence.add_log_lines(["read packet: $vCont;c#a8",
+                                          {"direction": "send",
+                                           "regex": r"^\$T([0-9a-fA-F]{2}).*#[0-9a-fA-F]{2}$",
+                                           "capture": {1: "hex_exit_code"}},
+                                          ],
+                                         True)
+
+        # Send g packet to retrieve the register bank
+        if thread_id:
+            g_request = "read packet: $g;thread:{:x}#00".format(thread_id)
+        else:
+            g_request = "read packet: $g#00"
+        self.test_sequence.add_log_lines(
+            [g_request,
+             {"direction": "send", "regex": r"^\$(.+)#[0-9a-fA-F]{2}$",
+              "capture": {1: "register_bank"}}],
+            True)
+        context = self.expect_gdbremote_sequence()
+        self.assertIsNotNone(context)
+        reg_bank = context.get("register_bank")
+        self.assertTrue(reg_bank[0] != 'E')
+
+        byte_order = self.get_target_byte_order()
+        get_reg_value = lambda reg_name : _extract_register_value(
+            reg_infos[reg_name], reg_bank, byte_order)
+
+        self.assertEqual(['0x0102030405060708'], get_reg_value('r8'))
+        self.assertEqual(['0x1112131415161718'], get_reg_value('r9'))
+        self.assertEqual(['0x2122232425262728'], get_reg_value('r10'))
+        self.assertEqual(['0x3132333435363738'], get_reg_value('r11'))
+        self.assertEqual(['0x4142434445464748'], get_reg_value('r12'))
+        self.assertEqual(['0x5152535455565758'], get_reg_value('r13'))
+        self.assertEqual(['0x6162636465666768'], get_reg_value('r14'))
+        self.assertEqual(['0x7172737475767778'], get_reg_value('r15'))
+
+        self.assertEqual(
+            ['0x020406080a0c0e01', '0x030507090b0d0f00'], get_reg_value('xmm8'))
+        self.assertEqual(
+            ['0x121416181a1c1e11', '0x131517191b1d1f10'], get_reg_value('xmm9'))
+        self.assertEqual(
+            ['0x222426282a2c2e21', '0x232527292b2d2f20'], get_reg_value('xmm10'))
+        self.assertEqual(
+            ['0x323436383a3c3e31', '0x333537393b3d3f30'], get_reg_value('xmm11'))
+        self.assertEqual(
+            ['0x424446484a4c4e41', '0x434547494b4d4f40'], get_reg_value('xmm12'))
+        self.assertEqual(
+            ['0x525456585a5c5e51', '0x535557595b5d5f50'], get_reg_value('xmm13'))
+        self.assertEqual(
+            ['0x626466686a6c6e61', '0x636567696b6d6f60'], get_reg_value('xmm14'))
+        self.assertEqual(
+            ['0x727476787a7c7e71', '0x737577797b7d7f70'], get_reg_value('xmm15'))
+
+    @llgs_test
+    def test_g_returns_correct_data_with_suffix_llgs(self):
+        self.init_llgs_test()
+        self.build()
+        self.set_inferior_startup_launch()
+        self.g_returns_correct_data(True)
+
+    @llgs_test
+    def test_g_returns_correct_data_no_suffix_llgs(self):
+        self.init_llgs_test()
+        self.build()
+        self.set_inferior_startup_launch()
+        self.g_returns_correct_data(False)

Added: lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/register-reading/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/register-reading/main.cpp?rev=362063&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/register-reading/main.cpp (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/tools/lldb-server/register-reading/main.cpp Thu May 30 00:25:22 2019
@@ -0,0 +1,54 @@
+#include <cstdint>
+
+struct alignas(16) xmm_t {
+  uint64_t a, b;
+};
+
+int main() {
+  uint64_t r8 = 0x0102030405060708;
+  uint64_t r9 = 0x1112131415161718;
+  uint64_t r10 = 0x2122232425262728;
+  uint64_t r11 = 0x3132333435363738;
+  uint64_t r12 = 0x4142434445464748;
+  uint64_t r13 = 0x5152535455565758;
+  uint64_t r14 = 0x6162636465666768;
+  uint64_t r15 = 0x7172737475767778;
+
+  xmm_t xmm8 = {0x020406080A0C0E01, 0x030507090B0D0F00};
+  xmm_t xmm9 = {0x121416181A1C1E11, 0x131517191B1D1F10};
+  xmm_t xmm10 = {0x222426282A2C2E21, 0x232527292B2D2F20};
+  xmm_t xmm11 = {0x323436383A3C3E31, 0x333537393B3D3F30};
+  xmm_t xmm12 = {0x424446484A4C4E41, 0x434547494B4D4F40};
+  xmm_t xmm13 = {0x525456585A5C5E51, 0x535557595B5D5F50};
+  xmm_t xmm14 = {0x626466686A6C6E61, 0x636567696B6D6F60};
+  xmm_t xmm15 = {0x727476787A7C7E71, 0x737577797B7D7F70};
+
+  asm volatile("movq    %0, %%r8\n\t"
+               "movq    %1, %%r9\n\t"
+               "movq    %2, %%r10\n\t"
+               "movq    %3, %%r11\n\t"
+               "movq    %4, %%r12\n\t"
+               "movq    %5, %%r13\n\t"
+               "movq    %6, %%r14\n\t"
+               "movq    %7, %%r15\n\t"
+               "\n\t"
+               "movaps  %8, %%xmm8\n\t"
+               "movaps  %9, %%xmm9\n\t"
+               "movaps  %10, %%xmm10\n\t"
+               "movaps  %11, %%xmm11\n\t"
+               "movaps  %12, %%xmm12\n\t"
+               "movaps  %13, %%xmm13\n\t"
+               "movaps  %14, %%xmm14\n\t"
+               "movaps  %15, %%xmm15\n\t"
+               "\n\t"
+               "int3"
+               :
+               : "g"(r8), "g"(r9), "g"(r10), "g"(r11), "g"(r12), "g"(r13),
+                 "g"(r14), "g"(r15), "m"(xmm8), "m"(xmm9), "m"(xmm10),
+                 "m"(xmm11), "m"(xmm12), "m"(xmm13), "m"(xmm14), "m"(xmm15)
+               : "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
+                 "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm12", "%xmm13",
+                 "%xmm14", "%xmm15");
+
+  return 0;
+}

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp?rev=362063&r1=362062&r2=362063&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp Thu May 30 00:25:22 2019
@@ -187,6 +187,9 @@ void GDBRemoteCommunicationServerLLGS::R
       StringExtractorGDBRemote::eServerPacketType_jTraceConfigRead,
       &GDBRemoteCommunicationServerLLGS::Handle_jTraceConfigRead);
 
+  RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_g,
+                                &GDBRemoteCommunicationServerLLGS::Handle_g);
+
   RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_k,
                         [this](StringExtractorGDBRemote packet, Status &error,
                                bool &interrupt, bool &quit) {
@@ -1892,6 +1895,61 @@ GDBRemoteCommunicationServerLLGS::Handle
 }
 
 GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerLLGS::Handle_g(StringExtractorGDBRemote &packet) {
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
+
+  // Move past packet name.
+  packet.SetFilePos(strlen("g"));
+
+  // Get the thread to use.
+  NativeThreadProtocol *thread = GetThreadFromSuffix(packet);
+  if (!thread) {
+    LLDB_LOG(log, "failed, no thread available");
+    return SendErrorResponse(0x15);
+  }
+
+  // Get the thread's register context.
+  NativeRegisterContext &reg_ctx = thread->GetRegisterContext();
+
+  std::vector<uint8_t> regs_buffer;
+  for (uint32_t reg_num = 0; reg_num < reg_ctx.GetUserRegisterCount();
+       ++reg_num) {
+    const RegisterInfo *reg_info = reg_ctx.GetRegisterInfoAtIndex(reg_num);
+
+    if (reg_info == nullptr) {
+      LLDB_LOG(log, "failed to get register info for register index {0}",
+               reg_num);
+      return SendErrorResponse(0x15);
+    }
+
+    if (reg_info->value_regs != nullptr)
+      continue; // skip registers that are contained in other registers
+
+    RegisterValue reg_value;
+    Status error = reg_ctx.ReadRegister(reg_info, reg_value);
+    if (error.Fail()) {
+      LLDB_LOG(log, "failed to read register at index {0}", reg_num);
+      return SendErrorResponse(0x15);
+    }
+
+    if (reg_info->byte_offset + reg_info->byte_size >= regs_buffer.size())
+      // Resize the buffer to guarantee it can store the register offsetted
+      // data.
+      regs_buffer.resize(reg_info->byte_offset + reg_info->byte_size);
+
+    // Copy the register offsetted data to the buffer.
+    memcpy(regs_buffer.data() + reg_info->byte_offset, reg_value.GetBytes(),
+           reg_info->byte_size);
+  }
+
+  // Write the response.
+  StreamGDBRemote response;
+  response.PutBytesAsRawHex8(regs_buffer.data(), regs_buffer.size());
+
+  return SendPacketNoLock(response.GetString());
+}
+
+GDBRemoteCommunication::PacketResult
 GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) {
   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
 

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h?rev=362063&r1=362062&r2=362063&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h Thu May 30 00:25:22 2019
@@ -178,6 +178,8 @@ protected:
 
   PacketResult Handle_QPassSignals(StringExtractorGDBRemote &packet);
 
+  PacketResult Handle_g(StringExtractorGDBRemote &packet);
+
   void SetCurrentThreadID(lldb::tid_t tid);
 
   lldb::tid_t GetCurrentThreadID() const;

Modified: lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp?rev=362063&r1=362062&r2=362063&view=diff
==============================================================================
--- lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp (original)
+++ lldb/trunk/source/Utility/StringExtractorGDBRemote.cpp Thu May 30 00:25:22 2019
@@ -377,9 +377,7 @@ StringExtractorGDBRemote::GetServerPacke
     break;
 
   case 'g':
-    if (packet_size == 1)
-      return eServerPacketType_g;
-    break;
+    return eServerPacketType_g;
 
   case 'G':
     return eServerPacketType_G;




More information about the lldb-commits mailing list