[Lldb-commits] [lldb] e609fe6 - Revert "[lldb-server] jThreadsInfo returns stack memory"

Muhammad Omair Javaid via lldb-commits lldb-commits at lists.llvm.org
Tue Apr 7 05:20:26 PDT 2020


Author: Muhammad Omair Javaid
Date: 2020-04-07T17:11:22+05:00
New Revision: e609fe68b2c59b145c0a5c66bedbee2bff545200

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

LOG: Revert "[lldb-server] jThreadsInfo returns stack memory"

This reverts commit a53bf9b7c8f1ca950226a55c0e99fd706a7b6ad2.

Added: 
    

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

Removed: 
    lldb/test/API/tools/lldb-server/threads-info/Makefile
    lldb/test/API/tools/lldb-server/threads-info/TestGdbRemoteThreadsInfoMemory.py
    lldb/test/API/tools/lldb-server/threads-info/main.cpp


################################################################################
diff  --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index f8b09d5207ab..7d6cb2a3484b 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -31,7 +31,6 @@
 #include "lldb/Target/MemoryRegionInfo.h"
 #include "lldb/Utility/Args.h"
 #include "lldb/Utility/DataBuffer.h"
-#include "lldb/Utility/DataExtractor.h"
 #include "lldb/Utility/Endian.h"
 #include "lldb/Utility/LLDBAssert.h"
 #include "lldb/Utility/Log.h"
@@ -563,119 +562,6 @@ GetRegistersAsJSON(NativeThreadProtocol &thread) {
   return register_object;
 }
 
-static llvm::Optional<RegisterValue>
-GetRegisterValue(NativeRegisterContext &reg_ctx, uint32_t generic_regnum) {
-  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD));
-  uint32_t reg_num = reg_ctx.ConvertRegisterKindToRegisterNumber(
-      eRegisterKindGeneric, generic_regnum);
-  const RegisterInfo *const reg_info_p =
-      reg_ctx.GetRegisterInfoAtIndex(reg_num);
-
-  if (reg_info_p == nullptr || reg_info_p->value_regs != nullptr) {
-    LLDB_LOGF(log, "%s failed to get register info for register index %" PRIu32,
-              __FUNCTION__, reg_num);
-    return {};
-  }
-
-  RegisterValue reg_value;
-  Status error = reg_ctx.ReadRegister(reg_info_p, reg_value);
-  if (error.Fail()) {
-    LLDB_LOGF(log, "%s failed to read register '%s' index %" PRIu32 ": %s",
-              __FUNCTION__,
-              reg_info_p->name ? reg_info_p->name : "<unnamed-register>",
-              reg_num, error.AsCString());
-    return {};
-  }
-  return reg_value;
-}
-
-static json::Object CreateMemoryChunk(json::Array &stack_memory_chunks,
-                                      addr_t address,
-                                      std::vector<uint8_t> &bytes) {
-  json::Object chunk;
-  chunk.try_emplace("address", static_cast<int64_t>(address));
-  StreamString stream;
-  for (uint8_t b : bytes)
-    stream.PutHex8(b);
-  chunk.try_emplace("bytes", stream.GetString().str());
-  return chunk;
-}
-
-static json::Array GetStackMemoryAsJSON(NativeProcessProtocol &process,
-                                        NativeThreadProtocol &thread) {
-  uint32_t address_size = process.GetArchitecture().GetAddressByteSize();
-  const size_t kStackTopMemoryInfoWordSize = 12;
-  size_t stack_top_memory_info_byte_size =
-      kStackTopMemoryInfoWordSize * address_size;
-  const size_t kMaxStackSize = 128 * 1024;
-  const size_t kMaxFrameSize = 4 * 1024;
-  size_t fp_and_ra_size = 2 * address_size;
-  const size_t kMaxFrameCount = 128;
-
-  NativeRegisterContext &reg_ctx = thread.GetRegisterContext();
-
-  json::Array stack_memory_chunks;
-
-  lldb::addr_t sp_value;
-  if (llvm::Optional<RegisterValue> optional_sp_value =
-          GetRegisterValue(reg_ctx, LLDB_REGNUM_GENERIC_SP)) {
-    sp_value = optional_sp_value->GetAsUInt64();
-  } else {
-    return stack_memory_chunks;
-  }
-  lldb::addr_t fp_value;
-  if (llvm::Optional<RegisterValue> optional_fp_value =
-          GetRegisterValue(reg_ctx, LLDB_REGNUM_GENERIC_FP)) {
-    fp_value = optional_fp_value->GetAsUInt64();
-  } else {
-    return stack_memory_chunks;
-  }
-
-  // First, make sure we copy the top stack_top_memory_info_byte_size bytes
-  // from the stack.
-  size_t byte_count = std::min(stack_top_memory_info_byte_size,
-                               static_cast<size_t>(fp_value - sp_value));
-  std::vector<uint8_t> buf(byte_count, 0);
-
-  size_t bytes_read = 0;
-  Status error = process.ReadMemoryWithoutTrap(sp_value, buf.data(), byte_count,
-                                               bytes_read);
-  if (error.Success() && bytes_read > 0) {
-    buf.resize(bytes_read);
-    stack_memory_chunks.push_back(
-        CreateMemoryChunk(stack_memory_chunks, sp_value, buf));
-  }
-
-  // Additionally, try to walk the frame pointer link chain. If the frame
-  // is too big or if the frame pointer points too far, stop the walk.
-  addr_t max_frame_pointer = sp_value + kMaxStackSize;
-  for (size_t i = 0; i < kMaxFrameCount; i++) {
-    if (fp_value < sp_value || fp_value > sp_value + kMaxFrameSize ||
-        fp_value > max_frame_pointer)
-      break;
-
-    std::vector<uint8_t> fp_ra_buf(fp_and_ra_size, 0);
-    bytes_read = 0;
-    error = process.ReadMemoryWithoutTrap(fp_value, fp_ra_buf.data(),
-                                          fp_and_ra_size, bytes_read);
-    if (error.Fail() || bytes_read != fp_and_ra_size)
-      break;
-
-    stack_memory_chunks.push_back(
-        CreateMemoryChunk(stack_memory_chunks, fp_value, fp_ra_buf));
-
-    // Advance the stack pointer and the frame pointer.
-    sp_value = fp_value;
-    lldb_private::DataExtractor extractor(
-        fp_ra_buf.data(), fp_and_ra_size,
-        process.GetArchitecture().GetByteOrder(), address_size);
-    offset_t offset = 0;
-    fp_value = extractor.GetAddress(&offset);
-  }
-
-  return stack_memory_chunks;
-}
-
 static const char *GetStopReasonString(StopReason stop_reason) {
   switch (stop_reason) {
   case eStopReasonTrace:
@@ -740,9 +626,6 @@ GetJSONThreadsInfo(NativeProcessProtocol &process, bool abridged) {
       } else {
         return registers.takeError();
       }
-      json::Array stack_memory = GetStackMemoryAsJSON(process, *thread);
-      if (!stack_memory.empty())
-        thread_obj.try_emplace("memory", std::move(stack_memory));
     }
 
     thread_obj.try_emplace("tid", static_cast<int64_t>(tid));
@@ -947,7 +830,7 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread(
                   reg_set_p->name ? reg_set_p->name : "<unnamed-set>",
                   *reg_num_p);
       } else if (reg_info_p->value_regs == nullptr) {
-        // Only expedite registers that are not contained in other registers.
+        // Only expediate registers that are not contained in other registers.
         RegisterValue reg_value;
         Status error = reg_ctx.ReadRegister(reg_info_p, reg_value);
         if (error.Success()) {

diff  --git a/lldb/test/API/tools/lldb-server/TestGdbRemoteThreadsInStopReply.py b/lldb/test/API/tools/lldb-server/TestGdbRemoteThreadsInStopReply.py
index 4bce524ecae3..951932863409 100644
--- a/lldb/test/API/tools/lldb-server/TestGdbRemoteThreadsInStopReply.py
+++ b/lldb/test/API/tools/lldb-server/TestGdbRemoteThreadsInStopReply.py
@@ -158,7 +158,7 @@ def gather_threads_info_pcs(self, pc_register, little_endian):
         register = str(pc_register)
         # The jThreadsInfo response is not valid JSON data, so we have to
         # clean it up first.
-        jthreads_info = json.loads(self.decode_gdbremote_binary(threads_info))
+        jthreads_info = json.loads(re.sub(r"}]", "}", threads_info))
         thread_pcs = dict()
         for thread_info in jthreads_info:
             tid = thread_info["tid"]
@@ -167,34 +167,6 @@ def gather_threads_info_pcs(self, pc_register, little_endian):
 
         return thread_pcs
 
-    def gather_threads_info_memory(self):
-        self.reset_test_sequence()
-        self.test_sequence.add_log_lines(
-                [
-                    "read packet: $jThreadsInfo#c1",
-                    {
-                        "direction": "send",
-                        "regex": r"^\$(.*)#[0-9a-fA-F]{2}$",
-                        "capture": {
-                            1: "threads_info"}},
-                ],
-                True)
-
-        context = self.expect_gdbremote_sequence()
-        self.assertIsNotNone(context)
-        threads_info = context.get("threads_info")
-        # The jThreadsInfo response is not valid JSON data, so we have to
-        # clean it up first.
-        jthreads_info = json.loads(self.decode_gdbremote_binary(threads_info))
-        # Collect all the memory chunks from all threads
-        memory_chunks = dict()
-        for thread_info in jthreads_info:
-            chunk_list = thread_info["memory"]
-            self.assertNotEqual(len(chunk_list), 0)
-            for chunk in chunk_list:
-                memory_chunks[chunk["address"]] = chunk["bytes"]
-        return memory_chunks
-
     def QListThreadsInStopReply_supported(self):
         procs = self.prep_debug_monitor_and_inferior()
         self.test_sequence.add_log_lines(
@@ -341,45 +313,3 @@ def test_stop_reply_contains_thread_pcs_debugserver(self):
         self.build()
         self.set_inferior_startup_launch()
         self.stop_reply_contains_thread_pcs(5)
-
-    def read_memory_chunk(self, address, length):
-        self.test_sequence.add_log_lines(
-            ["read packet: $x{0:x},{1:x}#00".format(address, length),
-             {
-                 "direction": "send",
-                 "regex": r"^\$([\s\S]*)#[0-9a-fA-F]{2}$",
-                 "capture": {
-                     1: "contents"}},
-            ],
-            True)
-        contents = self.expect_gdbremote_sequence()["contents"]
-        contents = self.decode_gdbremote_binary(contents)
-        hex_contents = ""
-        for c in contents:
-            hex_contents += "%02x" % ord(c)
-        return hex_contents
-
-    def check_memory_chunks_equal(self, memory_chunks):
-        self.reset_test_sequence()
-        for address in memory_chunks:
-            contents = memory_chunks[address]
-            byte_size = len(contents) // 2
-            mem = self.read_memory_chunk(address, byte_size)
-            self.assertEqual(mem, contents)
-
-    def stop_reply_thread_info_correct_memory(self, thread_count):
-        # Run and stop the program.
-        self.gather_stop_reply_fields([], thread_count, [])
-        # Read memory chunks from jThreadsInfo.
-        memory_chunks = self.gather_threads_info_memory()
-        # Check the chunks are correct.
-        self.check_memory_chunks_equal(memory_chunks)
-
-    @expectedFailureAll(oslist=["windows"])
-    @skipIfNetBSD
-    @llgs_test
-    def test_stop_reply_thread_info_correct_memory_llgs(self):
-        self.init_llgs_test()
-        self.build()
-        self.set_inferior_startup_launch()
-        self.stop_reply_thread_info_correct_memory(5)

diff  --git a/lldb/test/API/tools/lldb-server/threads-info/Makefile b/lldb/test/API/tools/lldb-server/threads-info/Makefile
deleted file mode 100644
index 99998b20bcb0..000000000000
--- a/lldb/test/API/tools/lldb-server/threads-info/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-CXX_SOURCES := main.cpp
-
-include Makefile.rules

diff  --git a/lldb/test/API/tools/lldb-server/threads-info/TestGdbRemoteThreadsInfoMemory.py b/lldb/test/API/tools/lldb-server/threads-info/TestGdbRemoteThreadsInfoMemory.py
deleted file mode 100644
index 405221e9dc59..000000000000
--- a/lldb/test/API/tools/lldb-server/threads-info/TestGdbRemoteThreadsInfoMemory.py
+++ /dev/null
@@ -1,98 +0,0 @@
-
-import json
-
-import gdbremote_testcase
-from lldbsuite.test.decorators import *
-from lldbsuite.test.lldbtest import *
-
-def invert_byte_order(a):
-    return "".join(reversed([a[i:i+2] for i in range(0, len(a),2)]))
-
-def decode_hex(a):
-    return int(invert_byte_order(a), 16)
-
-def encode_hex(a):
-    return invert_byte_order("%016x" % a)
-
-class TestGdbRemoteThreadsInfoMemory(gdbremote_testcase.GdbRemoteTestCaseBase):
-
-    mydir = TestBase.compute_mydir(__file__)
-
-    @skipIf(archs=no_match(["x86_64"]))
-    def threadsInfoStackCorrect(self):
-        procs = self.prep_debug_monitor_and_inferior()
-
-        self.add_register_info_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}
-
-        # 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
-        self.test_sequence.add_log_lines(
-                [
-                    "read packet: $jThreadsInfo#c1",
-                    {
-                        "direction": "send",
-                        "regex": r"^\$(.*)#[0-9a-fA-F]{2}$",
-                        "capture": {
-                            1: "threads_info"}},
-                ],
-                True)
-
-        context = self.expect_gdbremote_sequence()
-        threads_info = context["threads_info"]
-        threads_info = json.loads(self.decode_gdbremote_binary(threads_info))
-        self.assertEqual(1, len(threads_info))
-        thread = threads_info[0]
-
-        # Read the stack pointer and the frame pointer from the jThreadsInfo
-        # reply.
-        rsp_id = reg_infos["rsp"]["lldb_register_index"]
-        sp = decode_hex(thread["registers"][str(rsp_id)])
-        rbp_id = reg_infos["rbp"]["lldb_register_index"]
-        fp = decode_hex(thread["registers"][str(rbp_id)])
-
-        # The top frame size is 3 words.
-        self.assertEqual(sp + 3 * 8, fp)
-
-        # Check the memory chunks.
-        chunks = thread["memory"]
-        self.assertEqual(3, len(chunks))
-        # First memory chunk should contain everything between sp and fp.
-        self.assertEqual(sp, chunks[0]["address"])
-        self.assertEqual(encode_hex(6) + encode_hex(5) + encode_hex(4),
-                         chunks[0]["bytes"])
-        # Second chunk should be at |fp|, its return address should be 0xfeed,
-        # and the next fp should 5 words away (3 values, ra and fp).
-        self.assertEqual(fp, chunks[1]["address"])
-        next_fp = fp + 5 * 8
-        self.assertEqual(encode_hex(next_fp) + encode_hex(0xfeed),
-                         chunks[1]["bytes"])
-        # Third chunk at |next_fp|, the next fp is 0x1008 bytes away and
-        # the ra is 0xf00d.
-        self.assertEqual(next_fp, chunks[2]["address"])
-        next_fp = next_fp + 0x1008
-        self.assertEqual(encode_hex(next_fp) + encode_hex(0xf00d),
-                         chunks[2]["bytes"])
-
-    @skipIfNetBSD
-    @llgs_test
-    def test_g_returns_correct_data_with_suffix_llgs(self):
-        self.init_llgs_test()
-        self.build()
-        self.set_inferior_startup_launch()
-        self.threadsInfoStackCorrect()

diff  --git a/lldb/test/API/tools/lldb-server/threads-info/main.cpp b/lldb/test/API/tools/lldb-server/threads-info/main.cpp
deleted file mode 100644
index 17d27b5d6b6e..000000000000
--- a/lldb/test/API/tools/lldb-server/threads-info/main.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-int main() {
-#if defined(__x86_64__)
-  // We setup two fake frames with frame pointer linking. The test will then
-  // check that lldb-server's jThreadsInfo reply includes the top frame's
-  // contents and the linked list of (frame-pointer, return-address) pairs. We
-  // pretend the next frame is too large to stop the frame walk.
-  asm volatile("movabsq $0xf00d, %rax\n\t"
-               "pushq   %rax\n\t"               // fake return address
-               "leaq    0x1000(%rsp), %rbp\n\t" // larger than kMaxFrameSize
-               "pushq   %rbp\n\t"
-               "movq    %rsp, %rbp\n\t"
-               "pushq   $1\n\t" // fake frame contents
-               "pushq   $2\n\t"
-               "pushq   $3\n\t"
-               "\n\t"
-               "movabsq $0xfeed, %rax\n\t"
-               "push    %rax\n\t" // second fake return address
-               "pushq   %rbp\n\t"
-               "movq    %rsp, %rbp\n\t"
-               "pushq   $4\n\t" // fake frame contents
-               "pushq   $5\n\t"
-               "pushq   $6\n\t"
-               "\n\t"
-               "int3\n\t");
-#endif
-  return 0;
-}


        


More information about the lldb-commits mailing list