Index: packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/TestMiniDumpNew.py =================================================================== --- packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/TestMiniDumpNew.py +++ packages/Python/lldbsuite/test/functionalities/postmortem/minidump-new/TestMiniDumpNew.py @@ -418,3 +418,65 @@ frame = thread.GetFrameAtIndex(1) value = frame.EvaluateExpression('x') self.assertEqual(value.GetValueAsSigned(), 3) + + def test_memory_regions_in_minidump(self): + """Test memory regions from a Minidump""" + # target create -c regions-linux-map.dmp + self.dbg.CreateTarget(None) + self.target = self.dbg.GetSelectedTarget() + self.process = self.target.LoadCore("regions-linux-map.dmp") + self.check_state() + + regions_count = 19 + region_info_list = self.process.GetMemoryRegions() + self.assertEqual(region_info_list.GetSize(), regions_count) + + def check_region(index, start, end, read, write, execute, mapped, name): + region_info = lldb.SBMemoryRegionInfo() + self.assertTrue( + self.process.GetMemoryRegionInfo(start, region_info).Success()) + self.assertEqual(start, region_info.GetRegionBase()) + self.assertEqual(end, region_info.GetRegionEnd()) + self.assertEqual(read, region_info.IsReadable()) + self.assertEqual(write, region_info.IsWritable()) + self.assertEqual(execute, region_info.IsExecutable()) + self.assertEqual(mapped, region_info.IsMapped()) + self.assertEqual(name, region_info.GetName()) + + # Ensure we have the same regions as SBMemoryRegionInfoList contains. + if index >= 0 and index < regions_count: + region_info_from_list = lldb.SBMemoryRegionInfo() + self.assertTrue(region_info_list.GetMemoryRegionAtIndex( + index, region_info_from_list)) + self.assertEqual(region_info_from_list, region_info) + + a = "/system/bin/app_process" + b = "/system/bin/linker" + c = "/system/lib/liblog.so" + d = "/system/lib/libc.so" + n = None + max_int = 0xffffffffffffffff + + # Test address before the first entry comes back with nothing mapped up + # to first valid region info + check_region(-1, 0x00000000, 0x400d9000, False, False, False, False, n) + check_region( 0, 0x400d9000, 0x400db000, True, False, True, True, a) + check_region( 1, 0x400db000, 0x400dc000, True, False, False, True, a) + check_region( 2, 0x400dc000, 0x400dd000, True, True, False, True, n) + check_region( 3, 0x400dd000, 0x400ec000, True, False, True, True, b) + check_region( 4, 0x400ec000, 0x400ed000, True, False, False, True, n) + check_region( 5, 0x400ed000, 0x400ee000, True, False, False, True, b) + check_region( 6, 0x400ee000, 0x400ef000, True, True, False, True, b) + check_region( 7, 0x400ef000, 0x400fb000, True, True, False, True, n) + check_region( 8, 0x400fb000, 0x400fc000, True, False, True, True, c) + check_region( 9, 0x400fc000, 0x400fd000, True, True, True, True, c) + check_region(10, 0x400fd000, 0x400ff000, True, False, True, True, c) + check_region(11, 0x400ff000, 0x40100000, True, False, False, True, c) + check_region(12, 0x40100000, 0x40101000, True, True, False, True, c) + check_region(13, 0x40101000, 0x40122000, True, False, True, True, d) + check_region(14, 0x40122000, 0x40123000, True, True, True, True, d) + check_region(15, 0x40123000, 0x40167000, True, False, True, True, d) + check_region(16, 0x40167000, 0x40169000, True, False, False, True, d) + check_region(17, 0x40169000, 0x4016b000, True, True, False, True, d) + check_region(18, 0x4016b000, 0x40176000, True, True, False, True, n) + check_region(-1, 0x40176000, max_int, False, False, False, False, n) Index: scripts/interface/SBMemoryRegionInfo.i =================================================================== --- scripts/interface/SBMemoryRegionInfo.i +++ scripts/interface/SBMemoryRegionInfo.i @@ -43,6 +43,9 @@ bool IsMapped (); + + const char * + GetName (); bool operator == (const lldb::SBMemoryRegionInfo &rhs) const; Index: source/Plugins/Process/minidump/MinidumpParser.h =================================================================== --- source/Plugins/Process/minidump/MinidumpParser.h +++ source/Plugins/Process/minidump/MinidumpParser.h @@ -87,6 +87,8 @@ MemoryRegionInfo GetMemoryRegionInfo(lldb::addr_t load_addr); + const MemoryRegionInfos &GetMemoryRegions(); + // Perform consistency checks and initialize internal data structures Status Initialize(); Index: source/Plugins/Process/minidump/MinidumpParser.cpp =================================================================== --- source/Plugins/Process/minidump/MinidumpParser.cpp +++ source/Plugins/Process/minidump/MinidumpParser.cpp @@ -537,6 +537,12 @@ 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 @@ -552,7 +558,7 @@ CreateRegionsCacheFromMemory64List(*this, m_regions); std::sort(m_regions.begin(), m_regions.end()); } - return FindMemoryRegion(load_addr); + return m_regions; } Status MinidumpParser::Initialize() { Index: source/Plugins/Process/minidump/MinidumpTypes.cpp =================================================================== --- source/Plugins/Process/minidump/MinidumpTypes.cpp +++ source/Plugins/Process/minidump/MinidumpTypes.cpp @@ -242,6 +242,8 @@ return {}; std::vector result; + result.reserve(header->num_of_entries); + for (uint64_t i = 0; i < header->num_of_entries; ++i) { result.push_back(reinterpret_cast( data.data() + i * header->size_of_entry)); Index: source/Plugins/Process/minidump/ProcessMinidump.h =================================================================== --- source/Plugins/Process/minidump/ProcessMinidump.h +++ source/Plugins/Process/minidump/ProcessMinidump.h @@ -78,6 +78,9 @@ Status GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &range_info) override; + Status GetMemoryRegions( + lldb_private::MemoryRegionInfos ®ion_list) override; + bool GetProcessInfo(ProcessInstanceInfo &info) override; Status WillResume() override { Index: source/Plugins/Process/minidump/ProcessMinidump.cpp =================================================================== --- source/Plugins/Process/minidump/ProcessMinidump.cpp +++ source/Plugins/Process/minidump/ProcessMinidump.cpp @@ -288,6 +288,12 @@ return Status(); } +Status ProcessMinidump::GetMemoryRegions( + lldb_private::MemoryRegionInfos ®ion_list) { + region_list = m_minidump_parser.GetMemoryRegions(); + return Status(); +} + void ProcessMinidump::Clear() { Process::m_thread_list.Clear(); } bool ProcessMinidump::UpdateThreadList(ThreadList &old_thread_list,