[Lldb-commits] [lldb] 7c603a4 - lldb/minidump: Refactor memory region computation code

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Fri Oct 25 15:33:50 PDT 2019


Author: Pavel Labath
Date: 2019-10-25T22:33:32Z
New Revision: 7c603a41e20f461cf38ec7359a9eaa118fc0db5d

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

LOG: lldb/minidump: Refactor memory region computation code

The goal of this refactor is to enable ProcessMinidump to take into
account the loaded modules and their sections when computing the
permissions of various ranges of memory, as discussed in D66638.

This patch moves some of the responsibility for computing the ranges
from MinidumpParser into ProcessMinidump. MinidumpParser still does the
parsing, but ProcessMinidump becomes responsible for answering the
actual queries about memory ranges. This will enable it (in a follow-up
patch) to augment the information obtained from the parser with data
obtained from actual object files.

The changes in the actual code are fairly straight-forward and just
involve moving code around. MinidumpParser::GetMemoryRegions is renamed
to BuildMemoryRegions to emphasize that it does no caching. The only new
thing is the additional bool flag returned from this function. This
indicates whether the returned regions describe all memory mapped into
the target process. Data obtained from /proc/maps and the MemoryInfoList
stream is considered to be exhaustive. Data obtained from Memory(64)List
is not. This will be used to determine whether we need to augment the
data or not.

This reshuffle means that it is no longer possible/easy to test some of
this code via unit tests, as constructing a ProcessMinidump instance is
hard. Instead, I update the unit tests to only test the parsing of the
actual data, and test the answering of queries through a lit test using
the "memory region" command. The patch also includes some tweaks to the
MemoryRegion class to make the unit tests easier to write.

Reviewers: amccarth, clayborg

Subscribers: lldb-commits

Differential Revision: https://reviews.llvm.org/D69035

Added: 
    lldb/source/Target/MemoryRegionInfo.cpp
    lldb/test/Shell/Minidump/memory-region.yaml

Modified: 
    lldb/include/lldb/Target/MemoryRegionInfo.h
    lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
    lldb/source/Plugins/Process/minidump/MinidumpParser.h
    lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
    lldb/source/Plugins/Process/minidump/ProcessMinidump.h
    lldb/source/Target/CMakeLists.txt
    lldb/unittests/Process/minidump/MinidumpParserTest.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Target/MemoryRegionInfo.h b/lldb/include/lldb/Target/MemoryRegionInfo.h
index 5cab2efea77c..c6c4e080f8df 100644
--- a/lldb/include/lldb/Target/MemoryRegionInfo.h
+++ b/lldb/include/lldb/Target/MemoryRegionInfo.h
@@ -21,11 +21,13 @@ class MemoryRegionInfo {
 
   enum OptionalBool { eDontKnow = -1, eNo = 0, eYes = 1 };
 
-  MemoryRegionInfo()
-      : m_range(), m_read(eDontKnow), m_write(eDontKnow), m_execute(eDontKnow),
-        m_mapped(eDontKnow), m_flash(eDontKnow), m_blocksize(0) {}
-
-  ~MemoryRegionInfo() {}
+  MemoryRegionInfo() = default;
+  MemoryRegionInfo(RangeType range, OptionalBool read, OptionalBool write,
+                   OptionalBool execute, OptionalBool mapped, ConstString name,
+                   OptionalBool flash, lldb::offset_t blocksize)
+      : m_range(range), m_read(read), m_write(write), m_execute(execute),
+        m_mapped(mapped), m_name(name), m_flash(flash), m_blocksize(blocksize) {
+  }
 
   RangeType &GetRange() { return m_range; }
 
@@ -88,20 +90,21 @@ class MemoryRegionInfo {
   bool operator==(const MemoryRegionInfo &rhs) const {
     return m_range == rhs.m_range && m_read == rhs.m_read &&
            m_write == rhs.m_write && m_execute == rhs.m_execute &&
-           m_mapped == rhs.m_mapped;
+           m_mapped == rhs.m_mapped && m_name == rhs.m_name &&
+           m_flash == rhs.m_flash && m_blocksize == rhs.m_blocksize;
   }
 
   bool operator!=(const MemoryRegionInfo &rhs) const { return !(*this == rhs); }
 
 protected:
   RangeType m_range;
-  OptionalBool m_read;
-  OptionalBool m_write;
-  OptionalBool m_execute;
-  OptionalBool m_mapped;
+  OptionalBool m_read = eDontKnow;
+  OptionalBool m_write = eDontKnow;
+  OptionalBool m_execute = eDontKnow;
+  OptionalBool m_mapped = eDontKnow;
   ConstString m_name;
-  OptionalBool m_flash;
-  lldb::offset_t m_blocksize;
+  OptionalBool m_flash = eDontKnow;
+  lldb::offset_t m_blocksize = 0;
 };
   
 inline bool operator<(const MemoryRegionInfo &lhs,
@@ -117,6 +120,9 @@ inline bool operator<(lldb::addr_t lhs, const MemoryRegionInfo &rhs) {
   return lhs < rhs.GetRange().GetRangeBase();
 }
 
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+                              const MemoryRegionInfo &Info);
+
 // Forward-declarable wrapper.
 class MemoryRegionInfos : public std::vector<lldb_private::MemoryRegionInfo> {
 public:

diff  --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
index 70933f91fe51..47cfd5bd2730 100644
--- a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
+++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
@@ -518,58 +518,26 @@ CreateRegionsCacheFromMemory64List(MinidumpParser &parser,
   return !regions.empty();
 }
 
-MemoryRegionInfo
-MinidumpParser::FindMemoryRegion(lldb::addr_t load_addr) const {
-  auto begin = m_regions.begin();
-  auto end = m_regions.end();
-  auto pos = std::lower_bound(begin, end, load_addr);
-  if (pos != end && pos->GetRange().Contains(load_addr))
-    return *pos;
-  
-  MemoryRegionInfo region;
-  if (pos == begin)
-    region.GetRange().SetRangeBase(0);
-  else {
-    auto prev = pos - 1;
-    if (prev->GetRange().Contains(load_addr))
-      return *prev;
-    region.GetRange().SetRangeBase(prev->GetRange().GetRangeEnd());
-  }
-  if (pos == end)
-    region.GetRange().SetRangeEnd(UINT64_MAX);
-  else
-    region.GetRange().SetRangeEnd(pos->GetRange().GetRangeBase());
-  region.SetReadable(MemoryRegionInfo::eNo);
-  region.SetWritable(MemoryRegionInfo::eNo);
-  region.SetExecutable(MemoryRegionInfo::eNo);
-  region.SetMapped(MemoryRegionInfo::eNo);
-  return region;
-}
-
-MemoryRegionInfo
-MinidumpParser::GetMemoryRegionInfo(lldb::addr_t load_addr) {
-  if (!m_parsed_regions)
-    GetMemoryRegions();
-  return FindMemoryRegion(load_addr);
-}
-
-const MemoryRegionInfos &MinidumpParser::GetMemoryRegions() {
-  if (!m_parsed_regions) {
-    m_parsed_regions = true;
-    // We haven't cached our memory regions yet we will create the region cache
-    // once. We create the region cache using the best source. We start with
-    // the linux maps since they are the most complete and have names for the
-    // regions. Next we try the MemoryInfoList since it has
-    // read/write/execute/map data, and then fall back to the MemoryList and
-    // Memory64List to just get a list of the memory that is mapped in this
-    // core file
-    if (!CreateRegionsCacheFromLinuxMaps(*this, m_regions))
-      if (!CreateRegionsCacheFromMemoryInfoList(*this, m_regions))
-        if (!CreateRegionsCacheFromMemoryList(*this, m_regions))
-          CreateRegionsCacheFromMemory64List(*this, m_regions);
-    llvm::sort(m_regions.begin(), m_regions.end());
-  }
-  return m_regions;
+std::pair<MemoryRegionInfos, bool> MinidumpParser::BuildMemoryRegions() {
+  // We create the region cache using the best source. We start with
+  // the linux maps since they are the most complete and have names for the
+  // regions. Next we try the MemoryInfoList since it has
+  // read/write/execute/map data, and then fall back to the MemoryList and
+  // Memory64List to just get a list of the memory that is mapped in this
+  // core file
+  MemoryRegionInfos result;
+  const auto &return_sorted = [&](bool is_complete) {
+    llvm::sort(result);
+    return std::make_pair(std::move(result), is_complete);
+  };
+  if (CreateRegionsCacheFromLinuxMaps(*this, result))
+    return return_sorted(true);
+  if (CreateRegionsCacheFromMemoryInfoList(*this, result))
+    return return_sorted(true);
+  if (CreateRegionsCacheFromMemoryList(*this, result))
+    return return_sorted(false);
+  CreateRegionsCacheFromMemory64List(*this, result);
+  return return_sorted(false);
 }
 
 #define ENUM_TO_CSTR(ST)                                                       \

diff  --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.h b/lldb/source/Plugins/Process/minidump/MinidumpParser.h
index d206fe6c9a00..4bcb2b47d45a 100644
--- a/lldb/source/Plugins/Process/minidump/MinidumpParser.h
+++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.h
@@ -88,9 +88,9 @@ class MinidumpParser {
 
   llvm::ArrayRef<uint8_t> GetMemory(lldb::addr_t addr, size_t size);
 
-  MemoryRegionInfo GetMemoryRegionInfo(lldb::addr_t load_addr);
-
-  const MemoryRegionInfos &GetMemoryRegions();
+  /// Returns a list of memory regions and a flag indicating whether the list is
+  /// complete (includes all regions mapped into the process memory).
+  std::pair<MemoryRegionInfos, bool> BuildMemoryRegions();
 
   static llvm::StringRef GetStreamTypeAsString(StreamType stream_type);
 
@@ -100,14 +100,10 @@ class MinidumpParser {
   MinidumpParser(lldb::DataBufferSP data_sp,
                  std::unique_ptr<llvm::object::MinidumpFile> file);
 
-  MemoryRegionInfo FindMemoryRegion(lldb::addr_t load_addr) const;
-
 private:
   lldb::DataBufferSP m_data_sp;
   std::unique_ptr<llvm::object::MinidumpFile> m_file;
   ArchSpec m_arch;
-  MemoryRegionInfos m_regions;
-  bool m_parsed_regions = false;
 };
 
 } // end namespace minidump

diff  --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
index e30a3c82a887..5dcaaaa34d91 100644
--- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
+++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp
@@ -334,15 +334,46 @@ ArchSpec ProcessMinidump::GetArchitecture() {
   return ArchSpec(triple);
 }
 
+void ProcessMinidump::BuildMemoryRegions() {
+  if (m_memory_regions)
+    return;
+  m_memory_regions.emplace();
+  bool is_complete;
+  std::tie(*m_memory_regions, is_complete) =
+      m_minidump_parser->BuildMemoryRegions();
+  // TODO: Use loaded modules to complete the region list.
+}
+
 Status ProcessMinidump::GetMemoryRegionInfo(lldb::addr_t load_addr,
-                                            MemoryRegionInfo &range_info) {
-  range_info = m_minidump_parser->GetMemoryRegionInfo(load_addr);
+                                            MemoryRegionInfo &region) {
+  BuildMemoryRegions();
+  auto pos = llvm::upper_bound(*m_memory_regions, load_addr);
+  if (pos != m_memory_regions->begin() &&
+      std::prev(pos)->GetRange().Contains(load_addr)) {
+    region = *std::prev(pos);
+    return Status();
+  }
+
+  if (pos == m_memory_regions->begin())
+    region.GetRange().SetRangeBase(0);
+  else
+    region.GetRange().SetRangeBase(std::prev(pos)->GetRange().GetRangeEnd());
+
+  if (pos == m_memory_regions->end())
+    region.GetRange().SetRangeEnd(UINT64_MAX);
+  else
+    region.GetRange().SetRangeEnd(pos->GetRange().GetRangeBase());
+
+  region.SetReadable(MemoryRegionInfo::eNo);
+  region.SetWritable(MemoryRegionInfo::eNo);
+  region.SetExecutable(MemoryRegionInfo::eNo);
+  region.SetMapped(MemoryRegionInfo::eNo);
   return Status();
 }
 
-Status ProcessMinidump::GetMemoryRegions(
-    lldb_private::MemoryRegionInfos &region_list) {
-  region_list = m_minidump_parser->GetMemoryRegions();
+Status ProcessMinidump::GetMemoryRegions(MemoryRegionInfos &region_list) {
+  BuildMemoryRegions();
+  region_list = *m_memory_regions;
   return Status();
 }
 

diff  --git a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
index 22dc24af7c0e..750164cf8aaf 100644
--- a/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
+++ b/lldb/source/Plugins/Process/minidump/ProcessMinidump.h
@@ -111,6 +111,9 @@ class ProcessMinidump : public Process {
   const minidump::ExceptionStream *m_active_exception;
   lldb::CommandObjectSP m_command_sp;
   bool m_is_wow64;
+  llvm::Optional<MemoryRegionInfos> m_memory_regions;
+
+  void BuildMemoryRegions();
 };
 
 } // namespace minidump

diff  --git a/lldb/source/Target/CMakeLists.txt b/lldb/source/Target/CMakeLists.txt
index bb74ff19e732..a92951e6a730 100644
--- a/lldb/source/Target/CMakeLists.txt
+++ b/lldb/source/Target/CMakeLists.txt
@@ -17,6 +17,7 @@ add_lldb_library(lldbTarget
   LanguageRuntime.cpp
   Memory.cpp
   MemoryHistory.cpp
+  MemoryRegionInfo.cpp
   ModuleCache.cpp
   OperatingSystem.cpp
   PathMappingList.cpp

diff  --git a/lldb/source/Target/MemoryRegionInfo.cpp b/lldb/source/Target/MemoryRegionInfo.cpp
new file mode 100644
index 000000000000..1feb84bffc58
--- /dev/null
+++ b/lldb/source/Target/MemoryRegionInfo.cpp
@@ -0,0 +1,20 @@
+//===-- MemoryRegionInfo.cpp ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/MemoryRegionInfo.h"
+
+llvm::raw_ostream &lldb_private::operator<<(llvm::raw_ostream &OS,
+                                            const MemoryRegionInfo &Info) {
+  return OS << llvm::formatv("MemoryRegionInfo([{0}, {1}), {2}, {3}, {4}, {5}, "
+                             "`{6}`, {7}, {8})",
+                             Info.GetRange().GetRangeBase(),
+                             Info.GetRange().GetRangeEnd(), Info.GetReadable(),
+                             Info.GetWritable(), Info.GetExecutable(),
+                             Info.GetMapped(), Info.GetName(), Info.GetFlash(),
+                             Info.GetBlocksize());
+}

diff  --git a/lldb/test/Shell/Minidump/memory-region.yaml b/lldb/test/Shell/Minidump/memory-region.yaml
new file mode 100644
index 000000000000..6727d28db17a
--- /dev/null
+++ b/lldb/test/Shell/Minidump/memory-region.yaml
@@ -0,0 +1,49 @@
+# Check that memory region parsing works correctly, with a particular emphasis
+# on the boundary conditions.
+
+# RUN: yaml2obj %s > %t
+# RUN: %lldb -b -c %t \
+# RUN:   -o "memory region 0" -o "memory region 0xd9000" \
+# RUN:   -o "memory region 0xd9001" -o "memory region 0xdafff" \
+# RUN:   -o "memory region 0xdb000" -o "memory region 0xdd000" | FileCheck %s
+
+# CHECK-LABEL: (lldb) memory region 0
+# CHECK: [0x0000000000000000-0x00000000000d9000) ---
+# CHECK-LABEL: (lldb) memory region 0xd9000
+# CHECK: [0x00000000000d9000-0x00000000000db000) r-x /system/bin/app_process
+# CHECK-LABEL: (lldb) memory region 0xd9001
+# CHECK: [0x00000000000d9000-0x00000000000db000) r-x /system/bin/app_process
+# CHECK-LABEL: (lldb) memory region 0xdafff
+# CHECK: [0x00000000000d9000-0x00000000000db000) r-x /system/bin/app_process
+# CHECK-LABEL: (lldb) memory region 0xdb000
+# CHECK: [0x00000000000db000-0x00000000000dc000) ---
+# CHECK-LABEL: (lldb) memory region 0xdd000
+# CHECK: [0x00000000000dd000-0xffffffffffffffff) ---
+
+--- !minidump
+Streams:         
+  - Type:            SystemInfo
+    Processor Arch:  AMD64
+    Platform ID:     Linux
+    CPU:             
+      Vendor ID:       GenuineIntel
+      Version Info:    0x00000000
+      Feature Info:    0x00000000
+  - Type:            LinuxProcStatus
+    Text:             |
+      Name:	nonexisting-module
+      State:	t (tracing stop)
+      Tgid:	29939
+      Ngid:	0
+      Pid:	29939
+      PPid:	29370
+      TracerPid:	29940
+      Uid:	1001	1001	1001	1001
+      Gid:	1001	1001	1001	1001
+
+  - Type:            LinuxMaps
+    Text:             |
+      000d9000-000db000 r-xp 00000000 b3:04 227        /system/bin/app_process
+      000dc000-000dd000 rw-p 00000000 00:00 0
+
+...

diff  --git a/lldb/unittests/Process/minidump/MinidumpParserTest.cpp b/lldb/unittests/Process/minidump/MinidumpParserTest.cpp
index b76bae1e6eaf..51c80ecd5075 100644
--- a/lldb/unittests/Process/minidump/MinidumpParserTest.cpp
+++ b/lldb/unittests/Process/minidump/MinidumpParserTest.cpp
@@ -332,34 +332,6 @@ TEST_F(MinidumpParserTest, FindMemoryRangeWithFullMemoryMinidump) {
   EXPECT_FALSE(parser->FindMemoryRange(0x7ffe0000 + 4096).hasValue());
 }
 
-void check_region(MinidumpParser &parser, lldb::addr_t addr, lldb::addr_t start,
-                  lldb::addr_t end, MemoryRegionInfo::OptionalBool read,
-                  MemoryRegionInfo::OptionalBool write,
-                  MemoryRegionInfo::OptionalBool exec,
-                  MemoryRegionInfo::OptionalBool mapped,
-                  ConstString name = ConstString()) {
-  SCOPED_TRACE(addr);
-  auto range_info = parser.GetMemoryRegionInfo(addr);
-  EXPECT_EQ(start, range_info.GetRange().GetRangeBase());
-  EXPECT_EQ(end, range_info.GetRange().GetRangeEnd());
-  EXPECT_EQ(read, range_info.GetReadable());
-  EXPECT_EQ(write, range_info.GetWritable());
-  EXPECT_EQ(exec, range_info.GetExecutable());
-  EXPECT_EQ(mapped, range_info.GetMapped());
-  EXPECT_EQ(name, range_info.GetName());
-}
-
-// Same as above function where addr == start
-void check_region(MinidumpParser &parser, lldb::addr_t start, lldb::addr_t end,
-                  MemoryRegionInfo::OptionalBool read,
-                  MemoryRegionInfo::OptionalBool write,
-                  MemoryRegionInfo::OptionalBool exec,
-                  MemoryRegionInfo::OptionalBool mapped,
-                  ConstString name = ConstString()) {
-  check_region(parser, start, start, end, read, write, exec, mapped, name);
-}
-
-
 constexpr auto yes = MemoryRegionInfo::eYes;
 constexpr auto no = MemoryRegionInfo::eNo;
 constexpr auto unknown = MemoryRegionInfo::eDontKnow;
@@ -378,17 +350,7 @@ TEST_F(MinidumpParserTest, GetMemoryRegionInfo) {
         Type:            [  ]
       - Base Address:    0x0000000000010000
         Allocation Protect: [ PAGE_READ_WRITE ]
-        Region Size:     0x0000000000010000
-        State:           [ MEM_COMMIT ]
-        Type:            [ MEM_MAPPED ]
-      - Base Address:    0x0000000000020000
-        Allocation Protect: [ PAGE_READ_WRITE ]
-        Region Size:     0x0000000000010000
-        State:           [ MEM_COMMIT ]
-        Type:            [ MEM_MAPPED ]
-      - Base Address:    0x0000000000030000
-        Allocation Protect: [ PAGE_READ_WRITE ]
-        Region Size:     0x0000000000001000
+        Region Size:     0x0000000000021000
         State:           [ MEM_COMMIT ]
         Type:            [ MEM_MAPPED ]
       - Base Address:    0x0000000000040000
@@ -413,21 +375,20 @@ TEST_F(MinidumpParserTest, GetMemoryRegionInfo) {
 )"),
                     llvm::Succeeded());
 
-  check_region(*parser, 0x00000000, 0x00010000, no, no, no, no);
-  check_region(*parser, 0x00010000, 0x00020000, yes, yes, no, yes);
-  check_region(*parser, 0x00020000, 0x00030000, yes, yes, no, yes);
-  check_region(*parser, 0x00030000, 0x00031000, yes, yes, no, yes);
-  check_region(*parser, 0x00031000, 0x00040000, no, no, no, no);
-  check_region(*parser, 0x00040000, 0x00041000, yes, no, no, yes);
-
-  // Check addresses contained inside ranges
-  check_region(*parser, 0x00000001, 0x00000000, 0x00010000, no, no, no, no);
-  check_region(*parser, 0x0000ffff, 0x00000000, 0x00010000, no, no, no, no);
-  check_region(*parser, 0x00010001, 0x00010000, 0x00020000, yes, yes, no, yes);
-  check_region(*parser, 0x0001ffff, 0x00010000, 0x00020000, yes, yes, no, yes);
-
-  // Test that an address after the last entry maps to rest of the memory space
-  check_region(*parser, 0x7fff0000, 0x7fff0000, UINT64_MAX, no, no, no, no);
+  EXPECT_THAT(
+      parser->BuildMemoryRegions(),
+      testing::Pair(testing::ElementsAre(
+                        MemoryRegionInfo({0x0, 0x10000}, no, no, no, no,
+                                         ConstString(), unknown, 0),
+                        MemoryRegionInfo({0x10000, 0x21000}, yes, yes, no, yes,
+                                         ConstString(), unknown, 0),
+                        MemoryRegionInfo({0x40000, 0x1000}, yes, no, no, yes,
+                                         ConstString(), unknown, 0),
+                        MemoryRegionInfo({0x7ffe0000, 0x1000}, yes, no, no, yes,
+                                         ConstString(), unknown, 0),
+                        MemoryRegionInfo({0x7ffe1000, 0xf000}, no, no, no, yes,
+                                         ConstString(), unknown, 0)),
+                    true));
 }
 
 TEST_F(MinidumpParserTest, GetMemoryRegionInfoFromMemoryList) {
@@ -443,30 +404,33 @@ TEST_F(MinidumpParserTest, GetMemoryRegionInfoFromMemoryList) {
 ...
 )"),
                     llvm::Succeeded());
+
   // Test we can get memory regions from the MINIDUMP_MEMORY_LIST stream when
   // we don't have a MemoryInfoListStream.
 
-  // Test addres before the first entry comes back with nothing mapped up
-  // to first valid region info
-  check_region(*parser, 0x00000000, 0x00001000, no, no, no, no);
-  check_region(*parser, 0x00001000, 0x00001010, yes, unknown, unknown, yes);
-  check_region(*parser, 0x00001010, 0x00002000, no, no, no, no);
-  check_region(*parser, 0x00002000, 0x00002020, yes, unknown, unknown, yes);
-  check_region(*parser, 0x00002020, UINT64_MAX, no, no, no, no);
+  EXPECT_THAT(
+      parser->BuildMemoryRegions(),
+      testing::Pair(testing::ElementsAre(
+                        MemoryRegionInfo({0x1000, 0x10}, yes, unknown, unknown,
+                                         yes, ConstString(), unknown, 0),
+                        MemoryRegionInfo({0x2000, 0x20}, yes, unknown, unknown,
+                                         yes, ConstString(), unknown, 0)),
+                    false));
 }
 
 TEST_F(MinidumpParserTest, GetMemoryRegionInfoFromMemory64List) {
   SetUpData("regions-memlist64.dmp");
+
   // Test we can get memory regions from the MINIDUMP_MEMORY64_LIST stream when
   // we don't have a MemoryInfoListStream.
-
-  // Test addres before the first entry comes back with nothing mapped up
-  // to first valid region info
-  check_region(*parser, 0x00000000, 0x00001000, no, no, no, no);
-  check_region(*parser, 0x00001000, 0x00001010, yes, unknown, unknown, yes);
-  check_region(*parser, 0x00001010, 0x00002000, no, no, no, no);
-  check_region(*parser, 0x00002000, 0x00002020, yes, unknown, unknown, yes);
-  check_region(*parser, 0x00002020, UINT64_MAX, no, no, no, no);
+  EXPECT_THAT(
+      parser->BuildMemoryRegions(),
+      testing::Pair(testing::ElementsAre(
+                        MemoryRegionInfo({0x1000, 0x10}, yes, unknown, unknown,
+                                         yes, ConstString(), unknown, 0),
+                        MemoryRegionInfo({0x2000, 0x20}, yes, unknown, unknown,
+                                         yes, ConstString(), unknown, 0)),
+                    false));
 }
 
 TEST_F(MinidumpParserTest, GetMemoryRegionInfoLinuxMaps) {
@@ -478,57 +442,34 @@ TEST_F(MinidumpParserTest, GetMemoryRegionInfoLinuxMaps) {
       400d9000-400db000 r-xp 00000000 b3:04 227        /system/bin/app_process
       400db000-400dc000 r--p 00001000 b3:04 227        /system/bin/app_process
       400dc000-400dd000 rw-p 00000000 00:00 0
-      400dd000-400ec000 r-xp 00000000 b3:04 300        /system/bin/linker
       400ec000-400ed000 r--p 00000000 00:00 0
-      400ed000-400ee000 r--p 0000f000 b3:04 300        /system/bin/linker
       400ee000-400ef000 rw-p 00010000 b3:04 300        /system/bin/linker
-      400ef000-400fb000 rw-p 00000000 00:00 0
-      400fb000-400fc000 r-xp 00000000 b3:04 1096       /system/lib/liblog.so
       400fc000-400fd000 rwxp 00001000 b3:04 1096       /system/lib/liblog.so
-      400fd000-400ff000 r-xp 00002000 b3:04 1096       /system/lib/liblog.so
-      400ff000-40100000 r--p 00003000 b3:04 1096       /system/lib/liblog.so
-      40100000-40101000 rw-p 00004000 b3:04 1096       /system/lib/liblog.so
-      40101000-40122000 r-xp 00000000 b3:04 955        /system/lib/libc.so
-      40122000-40123000 rwxp 00021000 b3:04 955        /system/lib/libc.so
-      40123000-40167000 r-xp 00022000 b3:04 955        /system/lib/libc.so
-      40167000-40169000 r--p 00065000 b3:04 955        /system/lib/libc.so
-      40169000-4016b000 rw-p 00067000 b3:04 955        /system/lib/libc.so
-      4016b000-40176000 rw-p 00000000 00:00 0
 
 ...
 )"),
                     llvm::Succeeded());
   // Test we can get memory regions from the linux /proc/<pid>/maps stream when
   // we don't have a MemoryInfoListStream.
-
-  // Test addres before the first entry comes back with nothing mapped up
-  // to first valid region info
-  ConstString a("/system/bin/app_process");
-  ConstString b("/system/bin/linker");
-  ConstString c("/system/lib/liblog.so");
-  ConstString d("/system/lib/libc.so");
-  ConstString n;
-  check_region(*parser, 0x00000000, 0x400d9000, no, no, no, no, n);
-  check_region(*parser, 0x400d9000, 0x400db000, yes, no, yes, yes, a);
-  check_region(*parser, 0x400db000, 0x400dc000, yes, no, no, yes, a);
-  check_region(*parser, 0x400dc000, 0x400dd000, yes, yes, no, yes, n);
-  check_region(*parser, 0x400dd000, 0x400ec000, yes, no, yes, yes, b);
-  check_region(*parser, 0x400ec000, 0x400ed000, yes, no, no, yes, n);
-  check_region(*parser, 0x400ed000, 0x400ee000, yes, no, no, yes, b);
-  check_region(*parser, 0x400ee000, 0x400ef000, yes, yes, no, yes, b);
-  check_region(*parser, 0x400ef000, 0x400fb000, yes, yes, no, yes, n);
-  check_region(*parser, 0x400fb000, 0x400fc000, yes, no, yes, yes, c);
-  check_region(*parser, 0x400fc000, 0x400fd000, yes, yes, yes, yes, c);
-  check_region(*parser, 0x400fd000, 0x400ff000, yes, no, yes, yes, c);
-  check_region(*parser, 0x400ff000, 0x40100000, yes, no, no, yes, c);
-  check_region(*parser, 0x40100000, 0x40101000, yes, yes, no, yes, c);
-  check_region(*parser, 0x40101000, 0x40122000, yes, no, yes, yes, d);
-  check_region(*parser, 0x40122000, 0x40123000, yes, yes, yes, yes, d);
-  check_region(*parser, 0x40123000, 0x40167000, yes, no, yes, yes, d);
-  check_region(*parser, 0x40167000, 0x40169000, yes, no, no, yes, d);
-  check_region(*parser, 0x40169000, 0x4016b000, yes, yes, no, yes, d);
-  check_region(*parser, 0x4016b000, 0x40176000, yes, yes, no, yes, n);
-  check_region(*parser, 0x40176000, UINT64_MAX, no, no, no, no, n);
+  ConstString app_process("/system/bin/app_process");
+  ConstString linker("/system/bin/linker");
+  ConstString liblog("/system/lib/liblog.so");
+  EXPECT_THAT(
+      parser->BuildMemoryRegions(),
+      testing::Pair(testing::ElementsAre(
+                        MemoryRegionInfo({0x400d9000, 0x2000}, yes, no, yes,
+                                         yes, app_process, unknown, 0),
+                        MemoryRegionInfo({0x400db000, 0x1000}, yes, no, no, yes,
+                                         app_process, unknown, 0),
+                        MemoryRegionInfo({0x400dc000, 0x1000}, yes, yes, no,
+                                         yes, ConstString(), unknown, 0),
+                        MemoryRegionInfo({0x400ec000, 0x1000}, yes, no, no, yes,
+                                         ConstString(), unknown, 0),
+                        MemoryRegionInfo({0x400ee000, 0x1000}, yes, yes, no,
+                                         yes, linker, unknown, 0),
+                        MemoryRegionInfo({0x400fc000, 0x1000}, yes, yes, yes,
+                                         yes, liblog, unknown, 0)),
+                    true));
 }
 
 // Windows Minidump tests


        


More information about the lldb-commits mailing list