[Lldb-commits] [lldb] [llvm] [Draft][LLDB][Minidump] Fix ProcessMinidump::GetMemoryRegions to include 64b regions when /proc/pid maps are missing. (PR #101086)
Jacob Lalonde via lldb-commits
lldb-commits at lists.llvm.org
Mon Jul 29 14:19:57 PDT 2024
https://github.com/Jlalond updated https://github.com/llvm/llvm-project/pull/101086
>From f42764d8e3981197f128829180d1f45639d57276 Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalonde at fb.com>
Date: Fri, 26 Jul 2024 14:14:42 -0700
Subject: [PATCH 1/6] Remove 64b specific method and create Cache from both
memory 32 and memory 64.
---
.../Process/minidump/MinidumpParser.cpp | 37 ++++++++-----------
1 file changed, 15 insertions(+), 22 deletions(-)
diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
index be9fae938e227..3eeb9474a938b 100644
--- a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
+++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
@@ -559,6 +559,20 @@ CreateRegionsCacheFromMemoryList(MinidumpParser &parser,
"Failed to read memory list: {0}");
return false;
}
+
+ size_t num_regions = ExpectedMemory->size();
+
+ llvm::ArrayRef<uint8_t> data =
+ parser.GetStream(StreamType::Memory64List);
+
+ llvm::ArrayRef<MinidumpMemoryDescriptor64> memory64_list;
+ if (!data.empty()) {
+ uint64_t base_rva;
+ std::tie(memory64_list, base_rva) =
+ MinidumpMemoryDescriptor64::ParseMemory64List(data);
+
+ num_regions += memory64_list.size();
+ }
regions.reserve(ExpectedMemory->size());
for (const MemoryDescriptor &memory_desc : *ExpectedMemory) {
if (memory_desc.Memory.DataSize == 0)
@@ -570,26 +584,7 @@ CreateRegionsCacheFromMemoryList(MinidumpParser &parser,
region.SetMapped(MemoryRegionInfo::eYes);
regions.push_back(region);
}
- regions.shrink_to_fit();
- return !regions.empty();
-}
-
-static bool
-CreateRegionsCacheFromMemory64List(MinidumpParser &parser,
- std::vector<MemoryRegionInfo> ®ions) {
- llvm::ArrayRef<uint8_t> data =
- parser.GetStream(StreamType::Memory64List);
- if (data.empty())
- return false;
- llvm::ArrayRef<MinidumpMemoryDescriptor64> memory64_list;
- uint64_t base_rva;
- std::tie(memory64_list, base_rva) =
- MinidumpMemoryDescriptor64::ParseMemory64List(data);
-
- if (memory64_list.empty())
- return false;
- regions.reserve(memory64_list.size());
for (const auto &memory_desc : memory64_list) {
if (memory_desc.data_size == 0)
continue;
@@ -620,9 +615,7 @@ std::pair<MemoryRegionInfos, bool> MinidumpParser::BuildMemoryRegions() {
return return_sorted(true);
if (CreateRegionsCacheFromMemoryInfoList(*this, result))
return return_sorted(true);
- if (CreateRegionsCacheFromMemoryList(*this, result))
- return return_sorted(false);
- CreateRegionsCacheFromMemory64List(*this, result);
+ CreateRegionsCacheFromMemoryList(*this, result);
return return_sorted(false);
}
>From 3d8c4c5a26faf036ca7981012aa8e34cf616456d Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalonde at fb.com>
Date: Sat, 27 Jul 2024 15:35:03 -0700
Subject: [PATCH 2/6] Add Mem64List to Obj2Yaml and Yaml2Minidump
---
.../Minidump/MinidumpFileBuilder.cpp | 13 +-
.../Process/minidump/MinidumpParser.cpp | 3 +-
.../minidump-new/TestMiniDumpNew.py | 886 +++++++++---------
.../minidump-new/linux-x86_64_mem64.yaml | 23 +
.../minidump-new/regions-linux-map.yaml | 12 +-
llvm/include/llvm/BinaryFormat/Minidump.h | 12 +
llvm/include/llvm/Object/Minidump.h | 16 +-
llvm/include/llvm/ObjectYAML/MinidumpYAML.h | 24 +
llvm/lib/Object/Minidump.cpp | 41 +-
llvm/lib/ObjectYAML/MinidumpEmitter.cpp | 16 +
llvm/lib/ObjectYAML/MinidumpYAML.cpp | 36 +
11 files changed, 632 insertions(+), 450 deletions(-)
create mode 100644 lldb/test/API/functionalities/postmortem/minidump-new/linux-x86_64_mem64.yaml
diff --git a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
index de212c6b20da7..b941748bd7ccb 100644
--- a/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
+++ b/lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp
@@ -1020,15 +1020,17 @@ MinidumpFileBuilder::AddMemoryList_32(Process::CoreFileMemoryRanges &ranges) {
// With a size of the number of ranges as a 32 bit num
// And then the size of all the ranges
error = AddDirectory(StreamType::MemoryList,
- sizeof(llvm::support::ulittle32_t) +
+ sizeof(llvm::minidump::MemoryListHeader) +
descriptors.size() *
sizeof(llvm::minidump::MemoryDescriptor));
if (error.Fail())
return error;
+ llvm::minidump::MemoryListHeader list_header;
llvm::support::ulittle32_t memory_ranges_num =
static_cast<llvm::support::ulittle32_t>(descriptors.size());
- m_data.AppendData(&memory_ranges_num, sizeof(llvm::support::ulittle32_t));
+ list_header.NumberOfMemoryRanges = memory_ranges_num;
+ m_data.AppendData(&list_header, sizeof(llvm::minidump::MemoryListHeader));
// For 32b we can get away with writing off the descriptors after the data.
// This means no cleanup loop needed.
m_data.AppendData(descriptors.data(),
@@ -1050,9 +1052,10 @@ MinidumpFileBuilder::AddMemoryList_64(Process::CoreFileMemoryRanges &ranges) {
if (error.Fail())
return error;
+ llvm::minidump::Memory64ListHeader list_header;
llvm::support::ulittle64_t memory_ranges_num =
static_cast<llvm::support::ulittle64_t>(ranges.size());
- m_data.AppendData(&memory_ranges_num, sizeof(llvm::support::ulittle64_t));
+ list_header.NumberOfMemoryRanges = memory_ranges_num;
// Capture the starting offset for all the descriptors so we can clean them up
// if needed.
offset_t starting_offset =
@@ -1064,8 +1067,8 @@ MinidumpFileBuilder::AddMemoryList_64(Process::CoreFileMemoryRanges &ranges) {
(ranges.size() * sizeof(llvm::minidump::MemoryDescriptor_64));
llvm::support::ulittle64_t memory_ranges_base_rva =
static_cast<llvm::support::ulittle64_t>(base_rva);
- m_data.AppendData(&memory_ranges_base_rva,
- sizeof(llvm::support::ulittle64_t));
+ list_header.BaseRVA = memory_ranges_base_rva;
+ m_data.AppendData(&list_header, sizeof(llvm::minidump::Memory64ListHeader));
bool cleanup_required = false;
std::vector<MemoryDescriptor_64> descriptors;
diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
index 3eeb9474a938b..924c54196eb33 100644
--- a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
+++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
@@ -573,7 +573,8 @@ CreateRegionsCacheFromMemoryList(MinidumpParser &parser,
num_regions += memory64_list.size();
}
- regions.reserve(ExpectedMemory->size());
+
+ regions.reserve(num_regions);
for (const MemoryDescriptor &memory_desc : *ExpectedMemory) {
if (memory_desc.Memory.DataSize == 0)
continue;
diff --git a/lldb/test/API/functionalities/postmortem/minidump-new/TestMiniDumpNew.py b/lldb/test/API/functionalities/postmortem/minidump-new/TestMiniDumpNew.py
index 91fd2439492b5..cd6cc6aaaff19 100644
--- a/lldb/test/API/functionalities/postmortem/minidump-new/TestMiniDumpNew.py
+++ b/lldb/test/API/functionalities/postmortem/minidump-new/TestMiniDumpNew.py
@@ -52,442 +52,458 @@ def check_state(self):
self.dbg.SetOutputFileHandle(None, False)
self.dbg.SetErrorFileHandle(None, False)
- def test_loadcore_error_status(self):
- """Test the SBTarget.LoadCore(core, error) overload."""
- minidump_path = self.getBuildArtifact("linux-x86_64.dmp")
- self.yaml2obj("linux-x86_64.yaml", minidump_path)
- self.target = self.dbg.CreateTarget(None)
- error = lldb.SBError()
- self.process = self.target.LoadCore(minidump_path, error)
- self.assertTrue(self.process, PROCESS_IS_VALID)
- self.assertSuccess(error)
-
- def test_loadcore_error_status_failure(self):
- """Test the SBTarget.LoadCore(core, error) overload."""
- self.target = self.dbg.CreateTarget(None)
- error = lldb.SBError()
- self.process = self.target.LoadCore("non-existent.dmp", error)
- self.assertFalse(self.process, PROCESS_IS_VALID)
- self.assertTrue(error.Fail())
-
- def test_process_info_in_minidump(self):
- """Test that lldb can read the process information from the Minidump."""
- self.process_from_yaml("linux-x86_64.yaml")
- self.assertTrue(self.process, PROCESS_IS_VALID)
- self.assertEqual(self.process.GetNumThreads(), 1)
- self.assertEqual(self.process.GetProcessID(), self._linux_x86_64_pid)
- self.check_state()
-
- def test_memory_region_name(self):
- self.process_from_yaml("regions-linux-map.yaml")
- result = lldb.SBCommandReturnObject()
- addr_region_name_pairs = [
- ("0x400d9000", "/system/bin/app_process"),
- ("0x400db000", "/system/bin/app_process"),
- ("0x400dd000", "/system/bin/linker"),
- ("0x400ed000", "/system/bin/linker"),
- ("0x400ee000", "/system/bin/linker"),
- ("0x400fb000", "/system/lib/liblog.so"),
- ("0x400fc000", "/system/lib/liblog.so"),
- ("0x400fd000", "/system/lib/liblog.so"),
- ("0x400ff000", "/system/lib/liblog.so"),
- ("0x40100000", "/system/lib/liblog.so"),
- ("0x40101000", "/system/lib/libc.so"),
- ("0x40122000", "/system/lib/libc.so"),
- ("0x40123000", "/system/lib/libc.so"),
- ("0x40167000", "/system/lib/libc.so"),
- ("0x40169000", "/system/lib/libc.so"),
- ]
- ci = self.dbg.GetCommandInterpreter()
- for addr, region_name in addr_region_name_pairs:
- command = "memory region " + addr
- ci.HandleCommand(command, result, False)
- message = 'Ensure memory "%s" shows up in output for "%s"' % (
- region_name,
- command,
- )
- self.assertIn(region_name, result.GetOutput(), message)
-
- def test_thread_info_in_minidump(self):
- """Test that lldb can read the thread information from the Minidump."""
- self.process_from_yaml("linux-x86_64.yaml")
- self.check_state()
- # This process crashed due to a segmentation fault in its
- # one and only thread.
- self.assertEqual(self.process.GetNumThreads(), 1)
- thread = self.process.GetThreadAtIndex(0)
- self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonSignal)
- stop_description = thread.GetStopDescription(256)
- self.assertIn("SIGSEGV", stop_description)
-
- @skipIfLLVMTargetMissing("X86")
- def test_stack_info_in_minidump(self):
- """Test that we can see a trivial stack in a breakpad-generated Minidump."""
- # target create linux-x86_64 -c linux-x86_64.dmp
- self.dbg.CreateTarget("linux-x86_64")
- self.target = self.dbg.GetSelectedTarget()
- self.process = self.target.LoadCore("linux-x86_64.dmp")
- self.check_state()
- self.assertEqual(self.process.GetNumThreads(), 1)
- self.assertEqual(self.process.GetProcessID(), self._linux_x86_64_pid)
- thread = self.process.GetThreadAtIndex(0)
- # frame #0: linux-x86_64`crash()
- # frame #1: linux-x86_64`_start
- self.assertEqual(thread.GetNumFrames(), 2)
- frame = thread.GetFrameAtIndex(0)
- self.assertTrue(frame.IsValid())
- self.assertTrue(frame.GetModule().IsValid())
- pc = frame.GetPC()
- eip = frame.FindRegister("pc")
- self.assertTrue(eip.IsValid())
- self.assertEqual(pc, eip.GetValueAsUnsigned())
-
- def test_snapshot_minidump_dump_requested(self):
- """Test that if we load a snapshot minidump file (meaning the process
- did not crash) with exception code "DUMP_REQUESTED" there is no stop reason."""
- # target create -c linux-x86_64_not_crashed.dmp
- self.dbg.CreateTarget(None)
- self.target = self.dbg.GetSelectedTarget()
- self.process = self.target.LoadCore("linux-x86_64_not_crashed.dmp")
- self.check_state()
- self.assertEqual(self.process.GetNumThreads(), 1)
- thread = self.process.GetThreadAtIndex(0)
- self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonNone)
- stop_description = thread.GetStopDescription(256)
- self.assertEqual(stop_description, "")
-
- def test_snapshot_minidump_null_exn_code(self):
- """Test that if we load a snapshot minidump file (meaning the process
- did not crash) with exception code zero there is no stop reason."""
- self.process_from_yaml("linux-x86_64_null_signal.yaml")
- self.check_state()
- self.assertEqual(self.process.GetNumThreads(), 1)
- thread = self.process.GetThreadAtIndex(0)
- self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonNone)
- stop_description = thread.GetStopDescription(256)
- self.assertEqual(stop_description, "")
-
- def check_register_unsigned(self, set, name, expected):
- reg_value = set.GetChildMemberWithName(name)
- self.assertTrue(
- reg_value.IsValid(), 'Verify we have a register named "%s"' % (name)
- )
- self.assertEqual(
- reg_value.GetValueAsUnsigned(),
- expected,
- 'Verify "%s" == %i' % (name, expected),
- )
-
- def check_register_string_value(self, set, name, expected, format):
- reg_value = set.GetChildMemberWithName(name)
- self.assertTrue(
- reg_value.IsValid(), 'Verify we have a register named "%s"' % (name)
- )
- if format is not None:
- reg_value.SetFormat(format)
- self.assertEqual(
- reg_value.GetValue(),
- expected,
- 'Verify "%s" has string value "%s"' % (name, expected),
- )
-
- def test_arm64_registers(self):
- """Test ARM64 registers from a breakpad created minidump."""
- self.process_from_yaml("arm64-macos.yaml")
- self.check_state()
- self.assertEqual(self.process.GetNumThreads(), 1)
- thread = self.process.GetThreadAtIndex(0)
- self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonNone)
- stop_description = thread.GetStopDescription(256)
- self.assertEqual(stop_description, "")
- registers = thread.GetFrameAtIndex(0).GetRegisters()
- # Verify the GPR registers are all correct
- # Verify x0 - x31 register values
- gpr = registers.GetValueAtIndex(0)
- for i in range(32):
- v = i + 1 | i + 2 << 32 | i + 3 << 48
- w = i + 1
- self.check_register_unsigned(gpr, "x%i" % (i), v)
- self.check_register_unsigned(gpr, "w%i" % (i), w)
- # Verify arg1 - arg8 register values
- for i in range(1, 9):
- v = i | i + 1 << 32 | i + 2 << 48
- self.check_register_unsigned(gpr, "arg%i" % (i), v)
- i = 29
- v = i + 1 | i + 2 << 32 | i + 3 << 48
- self.check_register_unsigned(gpr, "fp", v)
- i = 30
- v = i + 1 | i + 2 << 32 | i + 3 << 48
- self.check_register_unsigned(gpr, "lr", v)
- i = 31
- v = i + 1 | i + 2 << 32 | i + 3 << 48
- self.check_register_unsigned(gpr, "sp", v)
- self.check_register_unsigned(gpr, "pc", 0x1000)
- self.check_register_unsigned(gpr, "cpsr", 0x11223344)
- self.check_register_unsigned(gpr, "psr", 0x11223344)
-
- # Verify the FPR registers are all correct
- fpr = registers.GetValueAtIndex(1)
- for i in range(32):
- v = "0x"
- d = "0x"
- s = "0x"
- h = "0x"
- for j in range(i + 15, i - 1, -1):
- v += "%2.2x" % (j)
- for j in range(i + 7, i - 1, -1):
- d += "%2.2x" % (j)
- for j in range(i + 3, i - 1, -1):
- s += "%2.2x" % (j)
- for j in range(i + 1, i - 1, -1):
- h += "%2.2x" % (j)
- self.check_register_string_value(fpr, "v%i" % (i), v, lldb.eFormatHex)
- self.check_register_string_value(fpr, "d%i" % (i), d, lldb.eFormatHex)
- self.check_register_string_value(fpr, "s%i" % (i), s, lldb.eFormatHex)
- self.check_register_string_value(fpr, "h%i" % (i), h, lldb.eFormatHex)
- self.check_register_unsigned(gpr, "fpsr", 0x55667788)
- self.check_register_unsigned(gpr, "fpcr", 0x99AABBCC)
-
- def verify_arm_registers(self, apple=False):
- """
- Verify values of all ARM registers from a breakpad created
- minidump.
- """
- if apple:
- self.process_from_yaml("arm-macos.yaml")
- else:
- self.process_from_yaml("arm-linux.yaml")
- self.check_state()
- self.assertEqual(self.process.GetNumThreads(), 1)
- thread = self.process.GetThreadAtIndex(0)
- self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonNone)
- stop_description = thread.GetStopDescription(256)
- self.assertEqual(stop_description, "")
- registers = thread.GetFrameAtIndex(0).GetRegisters()
- # Verify the GPR registers are all correct
- # Verify x0 - x31 register values
- gpr = registers.GetValueAtIndex(0)
- for i in range(1, 16):
- self.check_register_unsigned(gpr, "r%i" % (i), i + 1)
- # Verify arg1 - arg4 register values
- for i in range(1, 5):
- self.check_register_unsigned(gpr, "arg%i" % (i), i)
- if apple:
- self.check_register_unsigned(gpr, "fp", 0x08)
- else:
- self.check_register_unsigned(gpr, "fp", 0x0C)
- self.check_register_unsigned(gpr, "lr", 0x0F)
- self.check_register_unsigned(gpr, "sp", 0x0E)
- self.check_register_unsigned(gpr, "pc", 0x10)
- self.check_register_unsigned(gpr, "cpsr", 0x11223344)
-
- # Verify the FPR registers are all correct
- fpr = registers.GetValueAtIndex(1)
- # Check d0 - d31
- self.check_register_unsigned(gpr, "fpscr", 0x55667788AABBCCDD)
- for i in range(32):
- value = (i + 1) | (i + 1) << 8 | (i + 1) << 32 | (i + 1) << 48
- self.check_register_unsigned(fpr, "d%i" % (i), value)
- # Check s0 - s31
- for i in range(32):
- i_val = (i >> 1) + 1
- if i & 1:
- value = "%#8.8x" % (i_val | i_val << 16)
- else:
- value = "%#8.8x" % (i_val | i_val << 8)
- self.check_register_string_value(fpr, "s%i" % (i), value, lldb.eFormatHex)
- # Check q0 - q15
- for i in range(15):
- a = i * 2 + 1
- b = a + 1
- value = (
- "0x00%2.2x00%2.2x0000%2.2x%2.2x" "00%2.2x00%2.2x0000%2.2x%2.2x"
- ) % (b, b, b, b, a, a, a, a)
- self.check_register_string_value(fpr, "q%i" % (i), value, lldb.eFormatHex)
-
- def test_linux_arm_registers(self):
- """Test Linux ARM registers from a breakpad created minidump.
-
- The frame pointer is R11 for linux.
- """
- self.verify_arm_registers(apple=False)
-
- def test_apple_arm_registers(self):
- """Test Apple ARM registers from a breakpad created minidump.
-
- The frame pointer is R7 for linux.
- """
- self.verify_arm_registers(apple=True)
-
- def do_test_deeper_stack(self, binary, core, pid):
- target = self.dbg.CreateTarget(binary)
- process = target.LoadCore(core)
- thread = process.GetThreadAtIndex(0)
-
- self.assertEqual(process.GetProcessID(), pid)
-
- expected_stack = {1: "bar", 2: "foo", 3: "_start"}
- self.assertGreaterEqual(thread.GetNumFrames(), len(expected_stack))
- for index, name in expected_stack.items():
- frame = thread.GetFrameAtIndex(index)
- self.assertTrue(frame.IsValid())
- function_name = frame.GetFunctionName()
- self.assertIn(name, function_name)
-
- @skipIfLLVMTargetMissing("X86")
- def test_deeper_stack_in_minidump(self):
- """Test that we can examine a more interesting stack in a Minidump."""
- # Launch with the Minidump, and inspect the stack.
- # target create linux-x86_64_not_crashed -c linux-x86_64_not_crashed.dmp
- self.do_test_deeper_stack(
- "linux-x86_64_not_crashed",
- "linux-x86_64_not_crashed.dmp",
- self._linux_x86_64_not_crashed_pid,
- )
-
- def do_change_pid_in_minidump(self, core, newcore, offset, oldpid, newpid):
- """This assumes that the minidump is breakpad generated on Linux -
- meaning that the PID in the file will be an ascii string part of
- /proc/PID/status which is written in the file
- """
- shutil.copyfile(core, newcore)
- with open(newcore, "rb+") as f:
- f.seek(offset)
- currentpid = f.read(5).decode("utf-8")
- self.assertEqual(currentpid, oldpid)
-
- f.seek(offset)
- if len(newpid) < len(oldpid):
- newpid += " " * (len(oldpid) - len(newpid))
- newpid += "\n"
- f.write(newpid.encode("utf-8"))
-
- @skipIfLLVMTargetMissing("X86")
- def test_deeper_stack_in_minidump_with_same_pid_running(self):
- """Test that we read the information from the core correctly even if we
- have a running process with the same PID"""
- new_core = self.getBuildArtifact("linux-x86_64_not_crashed-pid.dmp")
- self.do_change_pid_in_minidump(
- "linux-x86_64_not_crashed.dmp",
- new_core,
- self._linux_x86_64_not_crashed_pid_offset,
- str(self._linux_x86_64_not_crashed_pid),
- str(os.getpid()),
- )
- self.do_test_deeper_stack("linux-x86_64_not_crashed", new_core, os.getpid())
-
- @skipIfLLVMTargetMissing("X86")
- def test_two_cores_same_pid(self):
- """Test that we handle the situation if we have two core files with the same PID"""
- new_core = self.getBuildArtifact("linux-x86_64_not_crashed-pid.dmp")
- self.do_change_pid_in_minidump(
- "linux-x86_64_not_crashed.dmp",
- new_core,
- self._linux_x86_64_not_crashed_pid_offset,
- str(self._linux_x86_64_not_crashed_pid),
- str(self._linux_x86_64_pid),
- )
- self.do_test_deeper_stack(
- "linux-x86_64_not_crashed", new_core, self._linux_x86_64_pid
- )
- self.test_stack_info_in_minidump()
-
- @skipIfLLVMTargetMissing("X86")
- def test_local_variables_in_minidump(self):
- """Test that we can examine local variables in a Minidump."""
- # Launch with the Minidump, and inspect a local variable.
- # target create linux-x86_64_not_crashed -c linux-x86_64_not_crashed.dmp
- self.target = self.dbg.CreateTarget("linux-x86_64_not_crashed")
- self.process = self.target.LoadCore("linux-x86_64_not_crashed.dmp")
- self.check_state()
- thread = self.process.GetThreadAtIndex(0)
- 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"""
- self.process_from_yaml("regions-linux-map.yaml")
+ # def test_loadcore_error_status(self):
+ # """Test the SBTarget.LoadCore(core, error) overload."""
+ # minidump_path = self.getBuildArtifact("linux-x86_64.dmp")
+ # self.yaml2obj("linux-x86_64.yaml", minidump_path)
+ # self.target = self.dbg.CreateTarget(None)
+ # error = lldb.SBError()
+ # self.process = self.target.LoadCore(minidump_path, error)
+ # self.assertTrue(self.process, PROCESS_IS_VALID)
+ # self.assertSuccess(error)
+
+ # def test_loadcore_error_status_failure(self):
+ # """Test the SBTarget.LoadCore(core, error) overload."""
+ # self.target = self.dbg.CreateTarget(None)
+ # error = lldb.SBError()
+ # self.process = self.target.LoadCore("non-existent.dmp", error)
+ # self.assertFalse(self.process, PROCESS_IS_VALID)
+ # self.assertTrue(error.Fail())
+
+ # def test_process_info_in_minidump(self):
+ # """Test that lldb can read the process information from the Minidump."""
+ # self.process_from_yaml("linux-x86_64.yaml")
+ # self.assertTrue(self.process, PROCESS_IS_VALID)
+ # self.assertEqual(self.process.GetNumThreads(), 1)
+ # self.assertEqual(self.process.GetProcessID(), self._linux_x86_64_pid)
+ # self.check_state()
+
+ # def test_memory_region_name(self):
+ # self.process_from_yaml("regions-linux-map.yaml")
+ # result = lldb.SBCommandReturnObject()
+ # addr_region_name_pairs = [
+ # ("0x400d9000", "/system/bin/app_process"),
+ # ("0x400db000", "/system/bin/app_process"),
+ # ("0x400dd000", "/system/bin/linker"),
+ # ("0x400ed000", "/system/bin/linker"),
+ # ("0x400ee000", "/system/bin/linker"),
+ # ("0x400fb000", "/system/lib/liblog.so"),
+ # ("0x400fc000", "/system/lib/liblog.so"),
+ # ("0x400fd000", "/system/lib/liblog.so"),
+ # ("0x400ff000", "/system/lib/liblog.so"),
+ # ("0x40100000", "/system/lib/liblog.so"),
+ # ("0x40101000", "/system/lib/libc.so"),
+ # ("0x40122000", "/system/lib/libc.so"),
+ # ("0x40123000", "/system/lib/libc.so"),
+ # ("0x40167000", "/system/lib/libc.so"),
+ # ("0x40169000", "/system/lib/libc.so"),
+ # ]
+ # ci = self.dbg.GetCommandInterpreter()
+ # for addr, region_name in addr_region_name_pairs:
+ # command = "memory region " + addr
+ # ci.HandleCommand(command, result, False)
+ # message = 'Ensure memory "%s" shows up in output for "%s"' % (
+ # region_name,
+ # command,
+ # )
+ # self.assertIn(region_name, result.GetOutput(), message)
+
+ # def test_thread_info_in_minidump(self):
+ # """Test that lldb can read the thread information from the Minidump."""
+ # self.process_from_yaml("linux-x86_64.yaml")
+ # self.check_state()
+ # # This process crashed due to a segmentation fault in its
+ # # one and only thread.
+ # self.assertEqual(self.process.GetNumThreads(), 1)
+ # thread = self.process.GetThreadAtIndex(0)
+ # self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonSignal)
+ # stop_description = thread.GetStopDescription(256)
+ # self.assertIn("SIGSEGV", stop_description)
+
+ # @skipIfLLVMTargetMissing("X86")
+ # def test_stack_info_in_minidump(self):
+ # """Test that we can see a trivial stack in a breakpad-generated Minidump."""
+ # # target create linux-x86_64 -c linux-x86_64.dmp
+ # self.dbg.CreateTarget("linux-x86_64")
+ # self.target = self.dbg.GetSelectedTarget()
+ # self.process = self.target.LoadCore("linux-x86_64.dmp")
+ # self.check_state()
+ # self.assertEqual(self.process.GetNumThreads(), 1)
+ # self.assertEqual(self.process.GetProcessID(), self._linux_x86_64_pid)
+ # thread = self.process.GetThreadAtIndex(0)
+ # # frame #0: linux-x86_64`crash()
+ # # frame #1: linux-x86_64`_start
+ # self.assertEqual(thread.GetNumFrames(), 2)
+ # frame = thread.GetFrameAtIndex(0)
+ # self.assertTrue(frame.IsValid())
+ # self.assertTrue(frame.GetModule().IsValid())
+ # pc = frame.GetPC()
+ # eip = frame.FindRegister("pc")
+ # self.assertTrue(eip.IsValid())
+ # self.assertEqual(pc, eip.GetValueAsUnsigned())
+
+ # def test_snapshot_minidump_dump_requested(self):
+ # """Test that if we load a snapshot minidump file (meaning the process
+ # did not crash) with exception code "DUMP_REQUESTED" there is no stop reason."""
+ # # target create -c linux-x86_64_not_crashed.dmp
+ # self.dbg.CreateTarget(None)
+ # self.target = self.dbg.GetSelectedTarget()
+ # self.process = self.target.LoadCore("linux-x86_64_not_crashed.dmp")
+ # self.check_state()
+ # self.assertEqual(self.process.GetNumThreads(), 1)
+ # thread = self.process.GetThreadAtIndex(0)
+ # self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonNone)
+ # stop_description = thread.GetStopDescription(256)
+ # self.assertEqual(stop_description, "")
+
+ # def test_snapshot_minidump_null_exn_code(self):
+ # """Test that if we load a snapshot minidump file (meaning the process
+ # did not crash) with exception code zero there is no stop reason."""
+ # self.process_from_yaml("linux-x86_64_null_signal.yaml")
+ # self.check_state()
+ # self.assertEqual(self.process.GetNumThreads(), 1)
+ # thread = self.process.GetThreadAtIndex(0)
+ # self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonNone)
+ # stop_description = thread.GetStopDescription(256)
+ # self.assertEqual(stop_description, "")
+
+ # def check_register_unsigned(self, set, name, expected):
+ # reg_value = set.GetChildMemberWithName(name)
+ # self.assertTrue(
+ # reg_value.IsValid(), 'Verify we have a register named "%s"' % (name)
+ # )
+ # self.assertEqual(
+ # reg_value.GetValueAsUnsigned(),
+ # expected,
+ # 'Verify "%s" == %i' % (name, expected),
+ # )
+
+ # def check_register_string_value(self, set, name, expected, format):
+ # reg_value = set.GetChildMemberWithName(name)
+ # self.assertTrue(
+ # reg_value.IsValid(), 'Verify we have a register named "%s"' % (name)
+ # )
+ # if format is not None:
+ # reg_value.SetFormat(format)
+ # self.assertEqual(
+ # reg_value.GetValue(),
+ # expected,
+ # 'Verify "%s" has string value "%s"' % (name, expected),
+ # )
+
+ # def test_arm64_registers(self):
+ # """Test ARM64 registers from a breakpad created minidump."""
+ # self.process_from_yaml("arm64-macos.yaml")
+ # self.check_state()
+ # self.assertEqual(self.process.GetNumThreads(), 1)
+ # thread = self.process.GetThreadAtIndex(0)
+ # self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonNone)
+ # stop_description = thread.GetStopDescription(256)
+ # self.assertEqual(stop_description, "")
+ # registers = thread.GetFrameAtIndex(0).GetRegisters()
+ # # Verify the GPR registers are all correct
+ # # Verify x0 - x31 register values
+ # gpr = registers.GetValueAtIndex(0)
+ # for i in range(32):
+ # v = i + 1 | i + 2 << 32 | i + 3 << 48
+ # w = i + 1
+ # self.check_register_unsigned(gpr, "x%i" % (i), v)
+ # self.check_register_unsigned(gpr, "w%i" % (i), w)
+ # # Verify arg1 - arg8 register values
+ # for i in range(1, 9):
+ # v = i | i + 1 << 32 | i + 2 << 48
+ # self.check_register_unsigned(gpr, "arg%i" % (i), v)
+ # i = 29
+ # v = i + 1 | i + 2 << 32 | i + 3 << 48
+ # self.check_register_unsigned(gpr, "fp", v)
+ # i = 30
+ # v = i + 1 | i + 2 << 32 | i + 3 << 48
+ # self.check_register_unsigned(gpr, "lr", v)
+ # i = 31
+ # v = i + 1 | i + 2 << 32 | i + 3 << 48
+ # self.check_register_unsigned(gpr, "sp", v)
+ # self.check_register_unsigned(gpr, "pc", 0x1000)
+ # self.check_register_unsigned(gpr, "cpsr", 0x11223344)
+ # self.check_register_unsigned(gpr, "psr", 0x11223344)
+
+ # # Verify the FPR registers are all correct
+ # fpr = registers.GetValueAtIndex(1)
+ # for i in range(32):
+ # v = "0x"
+ # d = "0x"
+ # s = "0x"
+ # h = "0x"
+ # for j in range(i + 15, i - 1, -1):
+ # v += "%2.2x" % (j)
+ # for j in range(i + 7, i - 1, -1):
+ # d += "%2.2x" % (j)
+ # for j in range(i + 3, i - 1, -1):
+ # s += "%2.2x" % (j)
+ # for j in range(i + 1, i - 1, -1):
+ # h += "%2.2x" % (j)
+ # self.check_register_string_value(fpr, "v%i" % (i), v, lldb.eFormatHex)
+ # self.check_register_string_value(fpr, "d%i" % (i), d, lldb.eFormatHex)
+ # self.check_register_string_value(fpr, "s%i" % (i), s, lldb.eFormatHex)
+ # self.check_register_string_value(fpr, "h%i" % (i), h, lldb.eFormatHex)
+ # self.check_register_unsigned(gpr, "fpsr", 0x55667788)
+ # self.check_register_unsigned(gpr, "fpcr", 0x99AABBCC)
+
+ # def verify_arm_registers(self, apple=False):
+ # """
+ # Verify values of all ARM registers from a breakpad created
+ # minidump.
+ # """
+ # if apple:
+ # self.process_from_yaml("arm-macos.yaml")
+ # else:
+ # self.process_from_yaml("arm-linux.yaml")
+ # self.check_state()
+ # self.assertEqual(self.process.GetNumThreads(), 1)
+ # thread = self.process.GetThreadAtIndex(0)
+ # self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonNone)
+ # stop_description = thread.GetStopDescription(256)
+ # self.assertEqual(stop_description, "")
+ # registers = thread.GetFrameAtIndex(0).GetRegisters()
+ # # Verify the GPR registers are all correct
+ # # Verify x0 - x31 register values
+ # gpr = registers.GetValueAtIndex(0)
+ # for i in range(1, 16):
+ # self.check_register_unsigned(gpr, "r%i" % (i), i + 1)
+ # # Verify arg1 - arg4 register values
+ # for i in range(1, 5):
+ # self.check_register_unsigned(gpr, "arg%i" % (i), i)
+ # if apple:
+ # self.check_register_unsigned(gpr, "fp", 0x08)
+ # else:
+ # self.check_register_unsigned(gpr, "fp", 0x0C)
+ # self.check_register_unsigned(gpr, "lr", 0x0F)
+ # self.check_register_unsigned(gpr, "sp", 0x0E)
+ # self.check_register_unsigned(gpr, "pc", 0x10)
+ # self.check_register_unsigned(gpr, "cpsr", 0x11223344)
+
+ # # Verify the FPR registers are all correct
+ # fpr = registers.GetValueAtIndex(1)
+ # # Check d0 - d31
+ # self.check_register_unsigned(gpr, "fpscr", 0x55667788AABBCCDD)
+ # for i in range(32):
+ # value = (i + 1) | (i + 1) << 8 | (i + 1) << 32 | (i + 1) << 48
+ # self.check_register_unsigned(fpr, "d%i" % (i), value)
+ # # Check s0 - s31
+ # for i in range(32):
+ # i_val = (i >> 1) + 1
+ # if i & 1:
+ # value = "%#8.8x" % (i_val | i_val << 16)
+ # else:
+ # value = "%#8.8x" % (i_val | i_val << 8)
+ # self.check_register_string_value(fpr, "s%i" % (i), value, lldb.eFormatHex)
+ # # Check q0 - q15
+ # for i in range(15):
+ # a = i * 2 + 1
+ # b = a + 1
+ # value = (
+ # "0x00%2.2x00%2.2x0000%2.2x%2.2x" "00%2.2x00%2.2x0000%2.2x%2.2x"
+ # ) % (b, b, b, b, a, a, a, a)
+ # self.check_register_string_value(fpr, "q%i" % (i), value, lldb.eFormatHex)
+
+ # def test_linux_arm_registers(self):
+ # """Test Linux ARM registers from a breakpad created minidump.
+
+ # The frame pointer is R11 for linux.
+ # """
+ # self.verify_arm_registers(apple=False)
+
+ # def test_apple_arm_registers(self):
+ # """Test Apple ARM registers from a breakpad created minidump.
+
+ # The frame pointer is R7 for linux.
+ # """
+ # self.verify_arm_registers(apple=True)
+
+ # def do_test_deeper_stack(self, binary, core, pid):
+ # target = self.dbg.CreateTarget(binary)
+ # process = target.LoadCore(core)
+ # thread = process.GetThreadAtIndex(0)
+
+ # self.assertEqual(process.GetProcessID(), pid)
+
+ # expected_stack = {1: "bar", 2: "foo", 3: "_start"}
+ # self.assertGreaterEqual(thread.GetNumFrames(), len(expected_stack))
+ # for index, name in expected_stack.items():
+ # frame = thread.GetFrameAtIndex(index)
+ # self.assertTrue(frame.IsValid())
+ # function_name = frame.GetFunctionName()
+ # self.assertIn(name, function_name)
+
+ # @skipIfLLVMTargetMissing("X86")
+ # def test_deeper_stack_in_minidump(self):
+ # """Test that we can examine a more interesting stack in a Minidump."""
+ # # Launch with the Minidump, and inspect the stack.
+ # # target create linux-x86_64_not_crashed -c linux-x86_64_not_crashed.dmp
+ # self.do_test_deeper_stack(
+ # "linux-x86_64_not_crashed",
+ # "linux-x86_64_not_crashed.dmp",
+ # self._linux_x86_64_not_crashed_pid,
+ # )
+
+ # def do_change_pid_in_minidump(self, core, newcore, offset, oldpid, newpid):
+ # """This assumes that the minidump is breakpad generated on Linux -
+ # meaning that the PID in the file will be an ascii string part of
+ # /proc/PID/status which is written in the file
+ # """
+ # shutil.copyfile(core, newcore)
+ # with open(newcore, "rb+") as f:
+ # f.seek(offset)
+ # currentpid = f.read(5).decode("utf-8")
+ # self.assertEqual(currentpid, oldpid)
+
+ # f.seek(offset)
+ # if len(newpid) < len(oldpid):
+ # newpid += " " * (len(oldpid) - len(newpid))
+ # newpid += "\n"
+ # f.write(newpid.encode("utf-8"))
+
+ # @skipIfLLVMTargetMissing("X86")
+ # def test_deeper_stack_in_minidump_with_same_pid_running(self):
+ # """Test that we read the information from the core correctly even if we
+ # have a running process with the same PID"""
+ # new_core = self.getBuildArtifact("linux-x86_64_not_crashed-pid.dmp")
+ # self.do_change_pid_in_minidump(
+ # "linux-x86_64_not_crashed.dmp",
+ # new_core,
+ # self._linux_x86_64_not_crashed_pid_offset,
+ # str(self._linux_x86_64_not_crashed_pid),
+ # str(os.getpid()),
+ # )
+ # self.do_test_deeper_stack("linux-x86_64_not_crashed", new_core, os.getpid())
+
+ # @skipIfLLVMTargetMissing("X86")
+ # def test_two_cores_same_pid(self):
+ # """Test that we handle the situation if we have two core files with the same PID"""
+ # new_core = self.getBuildArtifact("linux-x86_64_not_crashed-pid.dmp")
+ # self.do_change_pid_in_minidump(
+ # "linux-x86_64_not_crashed.dmp",
+ # new_core,
+ # self._linux_x86_64_not_crashed_pid_offset,
+ # str(self._linux_x86_64_not_crashed_pid),
+ # str(self._linux_x86_64_pid),
+ # )
+ # self.do_test_deeper_stack(
+ # "linux-x86_64_not_crashed", new_core, self._linux_x86_64_pid
+ # )
+ # self.test_stack_info_in_minidump()
+
+ # @skipIfLLVMTargetMissing("X86")
+ # def test_local_variables_in_minidump(self):
+ # """Test that we can examine local variables in a Minidump."""
+ # # Launch with the Minidump, and inspect a local variable.
+ # # target create linux-x86_64_not_crashed -c linux-x86_64_not_crashed.dmp
+ # self.target = self.dbg.CreateTarget("linux-x86_64_not_crashed")
+ # self.process = self.target.LoadCore("linux-x86_64_not_crashed.dmp")
+ # self.check_state()
+ # thread = self.process.GetThreadAtIndex(0)
+ # 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"""
+ # self.process_from_yaml("regions-linux-map.yaml")
+ # 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)
+
+ # @skipIfLLVMTargetMissing("X86")
+ # def test_minidump_sysroot(self):
+ # """Test that lldb can find a module referenced in an i386 linux minidump using the sysroot."""
+
+ # # Copy linux-x86_64 executable to tmp_sysroot/temp/test/ (since it was compiled as
+ # # /tmp/test/linux-x86_64)
+ # tmp_sysroot = os.path.join(self.getBuildDir(), "lldb_i386_mock_sysroot")
+ # executable = os.path.join(tmp_sysroot, "tmp", "test", "linux-x86_64")
+ # exe_dir = os.path.dirname(executable)
+ # lldbutil.mkdir_p(exe_dir)
+ # shutil.copyfile("linux-x86_64", executable)
+
+ # # Set sysroot and load core
+ # self.runCmd("platform select remote-linux --sysroot '%s'" % tmp_sysroot)
+ # self.process_from_yaml("linux-x86_64.yaml")
+ # self.check_state()
+
+ # # Check that we loaded the module from the sysroot
+ # self.assertEqual(self.target.GetNumModules(), 1)
+ # module = self.target.GetModuleAtIndex(0)
+ # spec_dir_norm = os.path.normcase(module.GetFileSpec().GetDirectory())
+ # exe_dir_norm = os.path.normcase(exe_dir)
+ # self.assertEqual(spec_dir_norm, exe_dir_norm)
+
+ def test_minidump_memory64list(self):
+ """Test that lldb can read from the memory64list in a minidump."""
+ self.process_from_yaml("linux-x86_64_mem64.yaml")
self.check_state()
- regions_count = 19
+ region_count = 1
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)
-
- @skipIfLLVMTargetMissing("X86")
- def test_minidump_sysroot(self):
- """Test that lldb can find a module referenced in an i386 linux minidump using the sysroot."""
-
- # Copy linux-x86_64 executable to tmp_sysroot/temp/test/ (since it was compiled as
- # /tmp/test/linux-x86_64)
- tmp_sysroot = os.path.join(self.getBuildDir(), "lldb_i386_mock_sysroot")
- executable = os.path.join(tmp_sysroot, "tmp", "test", "linux-x86_64")
- exe_dir = os.path.dirname(executable)
- lldbutil.mkdir_p(exe_dir)
- shutil.copyfile("linux-x86_64", executable)
-
- # Set sysroot and load core
- self.runCmd("platform select remote-linux --sysroot '%s'" % tmp_sysroot)
- self.process_from_yaml("linux-x86_64.yaml")
- self.check_state()
+ self.assertEqual(region_info_list.GetSize(), region_count)
+
+ region = lldb.SBMemoryRegionInfo()
+ self.assertTrue(region_info_list.GetMemoryRegionAtIndex(0, region))
+ self.assertEqual(region.GetRegionBase(), 0x07000FFD4BC15080)
+ self.assertTrue(region.GetRegionEnd(), 0x07000FFD4BC15080 + 8)
- # Check that we loaded the module from the sysroot
- self.assertEqual(self.target.GetNumModules(), 1)
- module = self.target.GetModuleAtIndex(0)
- spec_dir_norm = os.path.normcase(module.GetFileSpec().GetDirectory())
- exe_dir_norm = os.path.normcase(exe_dir)
- self.assertEqual(spec_dir_norm, exe_dir_norm)
+
diff --git a/lldb/test/API/functionalities/postmortem/minidump-new/linux-x86_64_mem64.yaml b/lldb/test/API/functionalities/postmortem/minidump-new/linux-x86_64_mem64.yaml
new file mode 100644
index 0000000000000..698ba90329a4e
--- /dev/null
+++ b/lldb/test/API/functionalities/postmortem/minidump-new/linux-x86_64_mem64.yaml
@@ -0,0 +1,23 @@
+--- !minidump
+Streams:
+ - Type: ThreadList
+ Threads:
+ - Thread Id: 0x000074DD
+ Context: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B0010000000000033000000000000000000000002020100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040109600000000000100000000000000000000000000000068E7D0C8FF7F000068E7D0C8FF7F000097E6D0C8FF7F000010109600000000000000000000000000020000000000000088E4D0C8FF7F0000603FFF85C77F0000F00340000000000080E7D0C8FF7F000000000000000000000000000000000000E0034000000000007F0300000000000000000000000000000000000000000000801F0000FFFF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF252525252525252525252525252525250000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+ Stack:
+ Start of Memory Range: 0x00007FFFC8D0E000
+ Content: DEADBEEFBAADF00D
+ - Type: ModuleList
+ Modules:
+ - Base of Image: 0x0000000000400000
+ Size of Image: 0x00001000
+ Module Name: '/tmp/test/linux-x86_64'
+ CodeView Record: 4C457042E35C283BC327C28762DB788BF5A4078BE2351448
+ - Type: Memory64List
+ Number of Memory Ranges: 1
+ Base RVA: 0x07000FFD4BC15080
+ Memory Ranges:
+ - Start of Memory Range: 0x07000FFD4BC15080
+ Content: 80000008
+
+...
diff --git a/lldb/test/API/functionalities/postmortem/minidump-new/regions-linux-map.yaml b/lldb/test/API/functionalities/postmortem/minidump-new/regions-linux-map.yaml
index 3c0961eba077d..4b6a844a38dd4 100644
--- a/lldb/test/API/functionalities/postmortem/minidump-new/regions-linux-map.yaml
+++ b/lldb/test/API/functionalities/postmortem/minidump-new/regions-linux-map.yaml
@@ -1,10 +1,10 @@
--- !minidump
-Streams:
+Streams:
- Type: SystemInfo
Processor Arch: ARM64
Platform ID: Linux
CSD Version: '15E216'
- CPU:
+ CPU:
CPUID: 0x00000000
- Type: MiscInfo
Content: 00000000010000007B000000000000000000000000000000
@@ -12,12 +12,12 @@ Streams:
Text: |
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
+ 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
+ 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
+ 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
@@ -28,6 +28,6 @@ Streams:
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
+ 4016b000-40176000 rw-p 00000000 00:00 0
...
diff --git a/llvm/include/llvm/BinaryFormat/Minidump.h b/llvm/include/llvm/BinaryFormat/Minidump.h
index 9669303252615..8054e81322a92 100644
--- a/llvm/include/llvm/BinaryFormat/Minidump.h
+++ b/llvm/include/llvm/BinaryFormat/Minidump.h
@@ -74,6 +74,18 @@ struct MemoryDescriptor_64 {
support::ulittle64_t StartOfMemoryRange;
support::ulittle64_t DataSize;
};
+static_assert(sizeof(MemoryDescriptor_64) == 16);
+
+struct MemoryListHeader {
+ support::ulittle32_t NumberOfMemoryRanges;
+};
+static_assert(sizeof(MemoryListHeader) == 4);
+
+struct Memory64ListHeader {
+ support::ulittle64_t NumberOfMemoryRanges;
+ support::ulittle64_t BaseRVA;
+};
+static_assert(sizeof(Memory64ListHeader) == 16);
struct MemoryInfoListHeader {
support::ulittle32_t SizeOfHeader;
diff --git a/llvm/include/llvm/Object/Minidump.h b/llvm/include/llvm/Object/Minidump.h
index e45d4de0090de..ad33bd6b42bde 100644
--- a/llvm/include/llvm/Object/Minidump.h
+++ b/llvm/include/llvm/Object/Minidump.h
@@ -52,6 +52,12 @@ class MinidumpFile : public Binary {
return getDataSlice(getData(), Desc.RVA, Desc.DataSize);
}
+ /// Returns the raw contents of an object given by the MemoryDescriptor. An
+ /// error is returned if the descriptor points outside of the minidump file,
+ /// or if there is no memory64list.
+ Expected<ArrayRef<uint8_t>>
+ getRawData(minidump::MemoryDescriptor_64 Desc) const;
+
/// Returns the minidump string at the given offset. An error is returned if
/// we fail to parse the string, or the string is invalid UTF16.
Expected<std::string> getString(size_t Offset) const;
@@ -103,6 +109,12 @@ class MinidumpFile : public Binary {
minidump::StreamType::MemoryList);
}
+ /// Returns the header to the memory 64 list stream. An error is returned if
+ /// the file does not contain this stream.
+ Expected<minidump::Memory64ListHeader> getMemoryList64Header() const;
+
+ Expected<ArrayRef<minidump::MemoryDescriptor_64>> getMemory64List() const;
+
class MemoryInfoIterator
: public iterator_facade_base<MemoryInfoIterator,
std::forward_iterator_tag,
@@ -153,14 +165,14 @@ class MinidumpFile : public Binary {
/// Return a slice of the given data array, with bounds checking.
static Expected<ArrayRef<uint8_t>> getDataSlice(ArrayRef<uint8_t> Data,
- size_t Offset, size_t Size);
+ uint64_t Offset, uint64_t Size);
/// Return the slice of the given data array as an array of objects of the
/// given type. The function checks that the input array is large enough to
/// contain the correct number of objects of the given type.
template <typename T>
static Expected<ArrayRef<T>> getDataSliceAs(ArrayRef<uint8_t> Data,
- size_t Offset, size_t Count);
+ uint64_t Offset, uint64_t Count);
MinidumpFile(MemoryBufferRef Source, const minidump::Header &Header,
ArrayRef<minidump::Directory> Streams,
diff --git a/llvm/include/llvm/ObjectYAML/MinidumpYAML.h b/llvm/include/llvm/ObjectYAML/MinidumpYAML.h
index b0cee541cef20..44500f5678803 100644
--- a/llvm/include/llvm/ObjectYAML/MinidumpYAML.h
+++ b/llvm/include/llvm/ObjectYAML/MinidumpYAML.h
@@ -29,6 +29,7 @@ struct Stream {
Exception,
MemoryInfoList,
MemoryList,
+ Memory64List,
ModuleList,
RawContent,
SystemInfo,
@@ -104,6 +105,22 @@ using ModuleListStream = detail::ListStream<detail::ParsedModule>;
using ThreadListStream = detail::ListStream<detail::ParsedThread>;
using MemoryListStream = detail::ListStream<detail::ParsedMemoryDescriptor>;
+/// Memory64ListStream minidump stream.
+struct Memory64ListStream : public Stream {
+ std::vector<minidump::MemoryDescriptor_64> Entries;
+ yaml::BinaryRef Content;
+
+ Memory64ListStream()
+ : Stream(StreamKind::Memory64List, minidump::StreamType::Memory64List) {}
+
+ explicit Memory64ListStream(std::vector<minidump::MemoryDescriptor_64> Entries)
+ : Stream(StreamKind::Memory64List, minidump::StreamType::Memory64List), Entries(Entries) {}
+
+ static bool classof(const Stream *S) {
+ return S->Kind == StreamKind::Memory64List;
+ }
+};
+
/// ExceptionStream minidump stream.
struct ExceptionStream : public Stream {
minidump::ExceptionStream MDExceptionStream;
@@ -244,6 +261,10 @@ template <> struct MappingContextTraits<minidump::MemoryDescriptor, BinaryRef> {
BinaryRef &Content);
};
+template <> struct MappingContextTraits<minidump::MemoryDescriptor_64, BinaryRef> {
+ static void mapping(IO &IO, minidump::MemoryDescriptor_64 &Memory, BinaryRef &Content);
+};
+
} // namespace yaml
} // namespace llvm
@@ -262,6 +283,7 @@ LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::CPUInfo::X86Info)
LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::Exception)
LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::MemoryInfo)
LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::VSFixedFileInfo)
+LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::minidump::MemoryDescriptor_64)
LLVM_YAML_DECLARE_MAPPING_TRAITS(
llvm::MinidumpYAML::MemoryListStream::entry_type)
@@ -270,11 +292,13 @@ LLVM_YAML_DECLARE_MAPPING_TRAITS(
LLVM_YAML_DECLARE_MAPPING_TRAITS(
llvm::MinidumpYAML::ThreadListStream::entry_type)
+
LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::MinidumpYAML::Stream>)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MinidumpYAML::MemoryListStream::entry_type)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MinidumpYAML::ModuleListStream::entry_type)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MinidumpYAML::ThreadListStream::entry_type)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::minidump::MemoryInfo)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::minidump::MemoryDescriptor_64)
LLVM_YAML_DECLARE_MAPPING_TRAITS(llvm::MinidumpYAML::Object)
diff --git a/llvm/lib/Object/Minidump.cpp b/llvm/lib/Object/Minidump.cpp
index 6febff89ac519..4a4553be1da4c 100644
--- a/llvm/lib/Object/Minidump.cpp
+++ b/llvm/lib/Object/Minidump.cpp
@@ -100,7 +100,7 @@ template Expected<ArrayRef<MemoryDescriptor>>
MinidumpFile::getListStream(StreamType) const;
Expected<ArrayRef<uint8_t>>
-MinidumpFile::getDataSlice(ArrayRef<uint8_t> Data, size_t Offset, size_t Size) {
+MinidumpFile::getDataSlice(ArrayRef<uint8_t> Data, uint64_t Offset, uint64_t Size) {
// Check for overflow.
if (Offset + Size < Offset || Offset + Size < Size ||
Offset + Size > Data.size())
@@ -154,3 +154,42 @@ MinidumpFile::create(MemoryBufferRef Source) {
return std::unique_ptr<MinidumpFile>(
new MinidumpFile(Source, Hdr, *ExpectedStreams, std::move(StreamMap)));
}
+
+Expected<minidump::Memory64ListHeader> MinidumpFile::getMemoryList64Header() const {
+ if (!StreamMap.contains(StreamType::Memory64List))
+ return createError("No memory64 list");
+
+ Expected<llvm::minidump::Memory64ListHeader> MemoryList64 = getStream<Memory64ListHeader>(StreamType::Memory64List);
+ if (!MemoryList64)
+ return MemoryList64.takeError();
+
+ return MemoryList64;
+}
+
+Expected<ArrayRef<MemoryDescriptor_64>> MinidumpFile::getMemory64List() const {
+ Expected<minidump::Memory64ListHeader> MemoryList64 = getMemoryList64Header();
+ if (!MemoryList64)
+ return MemoryList64.takeError();
+
+ uint64_t StartOffset = StreamMap.at(StreamType::Memory64List) + sizeof(Memory64ListHeader);
+ return getDataSliceAs<minidump::MemoryDescriptor_64>(getData(), StartOffset, sizeof(MemoryDescriptor_64) * MemoryList64->NumberOfMemoryRanges);
+}
+
+Expected<ArrayRef<uint8_t>>
+MinidumpFile::getRawData(minidump::MemoryDescriptor_64 Desc) const {
+ Expected<llvm::minidump::Memory64ListHeader> Memory64Header = getMemoryList64Header();
+ if (!Memory64Header)
+ return Memory64Header.takeError();
+ Expected<ArrayRef<MemoryDescriptor_64>> Memory64List = getMemory64List();
+ if (!Memory64List)
+ return Memory64List.takeError();
+
+ uint64_t RVA = Memory64Header->BaseRVA;
+ for (const MemoryDescriptor_64 &InnerDesc : Memory64List.get()) {
+ if (Desc.StartOfMemoryRange == InnerDesc.StartOfMemoryRange) {
+ return getDataSlice(getData(), RVA, Desc.DataSize);
+ }
+ }
+
+ return createEOFError();
+}
diff --git a/llvm/lib/ObjectYAML/MinidumpEmitter.cpp b/llvm/lib/ObjectYAML/MinidumpEmitter.cpp
index 24b521a9925c7..95f36b0f9ce91 100644
--- a/llvm/lib/ObjectYAML/MinidumpEmitter.cpp
+++ b/llvm/lib/ObjectYAML/MinidumpEmitter.cpp
@@ -136,6 +136,19 @@ static size_t layout(BlobAllocator &File, MinidumpYAML::ExceptionStream &S) {
return DataEnd;
}
+static size_t layout(BlobAllocator &File, MinidumpYAML::Memory64ListStream &S) {
+ size_t DataEnd = File.tell();
+ size_t BaseRVA = File.tell() + sizeof(minidump::Memory64ListHeader);
+ size_t NumStreams = S.Entries.size();
+ llvm::minidump::Memory64ListHeader Header;
+ Header.BaseRVA = BaseRVA;
+ Header.NumberOfMemoryRanges = NumStreams;
+ DataEnd += File.allocateObject(Header);
+ DataEnd += File.allocateArray(ArrayRef(S.Entries));
+
+ return DataEnd;
+}
+
static void layout(BlobAllocator &File, MemoryListStream::entry_type &Range) {
Range.Entry.Memory = layout(File, Range.Content);
}
@@ -190,6 +203,9 @@ static Directory layout(BlobAllocator &File, Stream &S) {
case Stream::StreamKind::MemoryList:
DataEnd = layout(File, cast<MemoryListStream>(S));
break;
+ case Stream::StreamKind::Memory64List:
+ DataEnd = layout(File, cast<Memory64ListStream>(S));
+ break;
case Stream::StreamKind::ModuleList:
DataEnd = layout(File, cast<ModuleListStream>(S));
break;
diff --git a/llvm/lib/ObjectYAML/MinidumpYAML.cpp b/llvm/lib/ObjectYAML/MinidumpYAML.cpp
index fdbd2d8e6dcbc..1f79f447ffd8b 100644
--- a/llvm/lib/ObjectYAML/MinidumpYAML.cpp
+++ b/llvm/lib/ObjectYAML/MinidumpYAML.cpp
@@ -75,6 +75,8 @@ Stream::StreamKind Stream::getKind(StreamType Type) {
return StreamKind::MemoryInfoList;
case StreamType::MemoryList:
return StreamKind::MemoryList;
+ case StreamType::Memory64List:
+ return StreamKind::Memory64List;
case StreamType::ModuleList:
return StreamKind::ModuleList;
case StreamType::SystemInfo:
@@ -103,6 +105,8 @@ std::unique_ptr<Stream> Stream::create(StreamType Type) {
return std::make_unique<MemoryInfoListStream>();
case StreamKind::MemoryList:
return std::make_unique<MemoryListStream>();
+ case StreamKind::Memory64List:
+ return std::make_unique<Memory64ListStream>();
case StreamKind::ModuleList:
return std::make_unique<ModuleListStream>();
case StreamKind::RawContent:
@@ -256,6 +260,11 @@ void yaml::MappingTraits<MemoryInfo>::mapping(IO &IO, MemoryInfo &Info) {
mapOptionalHex(IO, "Reserved1", Info.Reserved1, 0);
}
+void yaml::MappingTraits<MemoryDescriptor_64>::mapping(IO &IO, MemoryDescriptor_64 &Mem) {
+ mapRequiredHex(IO, "Start of memory range", Mem.StartOfMemoryRange);
+ mapRequiredHex(IO, "Data Size", Mem.DataSize);
+}
+
void yaml::MappingTraits<VSFixedFileInfo>::mapping(IO &IO,
VSFixedFileInfo &Info) {
mapOptionalHex(IO, "Signature", Info.Signature, 0);
@@ -312,6 +321,10 @@ static void streamMapping(yaml::IO &IO, MemoryListStream &Stream) {
IO.mapRequired("Memory Ranges", Stream.Entries);
}
+static void streamMapping(yaml::IO &IO, Memory64ListStream &Stream) {
+ IO.mapRequired("Memory Ranges", Stream.Entries);
+}
+
static void streamMapping(yaml::IO &IO, ModuleListStream &Stream) {
IO.mapRequired("Modules", Stream.Entries);
}
@@ -356,6 +369,12 @@ void yaml::MappingContextTraits<MemoryDescriptor, yaml::BinaryRef>::mapping(
IO.mapRequired("Content", Content);
}
+void yaml::MappingContextTraits<MemoryDescriptor_64, yaml::BinaryRef>::mapping(
+ IO &IO, MemoryDescriptor_64 &Memory, BinaryRef &Content) {
+ mapRequiredHex(IO, "Start of Memory Range", Memory.StartOfMemoryRange);
+ IO.mapRequired("Content", Content);
+}
+
void yaml::MappingTraits<ThreadListStream::entry_type>::mapping(
IO &IO, ThreadListStream::entry_type &T) {
mapRequiredHex(IO, "Thread Id", T.Entry.ThreadId);
@@ -416,6 +435,9 @@ void yaml::MappingTraits<std::unique_ptr<Stream>>::mapping(
case MinidumpYAML::Stream::StreamKind::MemoryList:
streamMapping(IO, llvm::cast<MemoryListStream>(*S));
break;
+ case MinidumpYAML::Stream::StreamKind::Memory64List:
+ streamMapping(IO, llvm::cast<Memory64ListStream>(*S));
+ break;
case MinidumpYAML::Stream::StreamKind::ModuleList:
streamMapping(IO, llvm::cast<ModuleListStream>(*S));
break;
@@ -442,6 +464,7 @@ std::string yaml::MappingTraits<std::unique_ptr<Stream>>::validate(
case MinidumpYAML::Stream::StreamKind::Exception:
case MinidumpYAML::Stream::StreamKind::MemoryInfoList:
case MinidumpYAML::Stream::StreamKind::MemoryList:
+ case MinidumpYAML::Stream::StreamKind::Memory64List:
case MinidumpYAML::Stream::StreamKind::ModuleList:
case MinidumpYAML::Stream::StreamKind::SystemInfo:
case MinidumpYAML::Stream::StreamKind::TextContent:
@@ -494,6 +517,19 @@ Stream::create(const Directory &StreamDesc, const object::MinidumpFile &File) {
}
return std::make_unique<MemoryListStream>(std::move(Ranges));
}
+ case StreamKind::Memory64List: {
+ auto ExpectedList = File.getMemory64List();
+ if (!ExpectedList)
+ return ExpectedList.takeError();
+ std::vector<MemoryDescriptor_64> Ranges;
+ for (const MemoryDescriptor_64 &MD : *ExpectedList) {
+ auto ExpectedContent = File.getRawData(MD);
+ if (!ExpectedContent)
+ return ExpectedContent.takeError();
+ Ranges.push_back(MD);
+ }
+ return std::make_unique<Memory64ListStream>(std::move(Ranges));
+ }
case StreamKind::ModuleList: {
auto ExpectedList = File.getModuleList();
if (!ExpectedList)
>From 64903f2b7ae3cc9544c4f7bf312b8c3d2ca08ea0 Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalonde at fb.com>
Date: Mon, 29 Jul 2024 09:06:50 -0700
Subject: [PATCH 3/6] Enable Memory64List for Object2Yaml emission
---
llvm/include/llvm/Object/Minidump.h | 11 ++++-----
llvm/lib/Object/Minidump.cpp | 35 ++++------------------------
llvm/lib/ObjectYAML/MinidumpYAML.cpp | 3 ---
3 files changed, 8 insertions(+), 41 deletions(-)
diff --git a/llvm/include/llvm/Object/Minidump.h b/llvm/include/llvm/Object/Minidump.h
index ad33bd6b42bde..2ebc0e07cd708 100644
--- a/llvm/include/llvm/Object/Minidump.h
+++ b/llvm/include/llvm/Object/Minidump.h
@@ -52,12 +52,6 @@ class MinidumpFile : public Binary {
return getDataSlice(getData(), Desc.RVA, Desc.DataSize);
}
- /// Returns the raw contents of an object given by the MemoryDescriptor. An
- /// error is returned if the descriptor points outside of the minidump file,
- /// or if there is no memory64list.
- Expected<ArrayRef<uint8_t>>
- getRawData(minidump::MemoryDescriptor_64 Desc) const;
-
/// Returns the minidump string at the given offset. An error is returned if
/// we fail to parse the string, or the string is invalid UTF16.
Expected<std::string> getString(size_t Offset) const;
@@ -111,7 +105,9 @@ class MinidumpFile : public Binary {
/// Returns the header to the memory 64 list stream. An error is returned if
/// the file does not contain this stream.
- Expected<minidump::Memory64ListHeader> getMemoryList64Header() const;
+ Expected<minidump::Memory64ListHeader> getMemoryList64Header() const {
+ return getStream<minidump::Memory64ListHeader>(minidump::StreamType::Memory64List);
+ }
Expected<ArrayRef<minidump::MemoryDescriptor_64>> getMemory64List() const;
@@ -220,6 +216,7 @@ Expected<ArrayRef<T>> MinidumpFile::getDataSliceAs(ArrayRef<uint8_t> Data,
getDataSlice(Data, Offset, sizeof(T) * Count);
if (!Slice)
return Slice.takeError();
+
return ArrayRef<T>(reinterpret_cast<const T *>(Slice->data()), Count);
}
diff --git a/llvm/lib/Object/Minidump.cpp b/llvm/lib/Object/Minidump.cpp
index 4a4553be1da4c..422b039e618a3 100644
--- a/llvm/lib/Object/Minidump.cpp
+++ b/llvm/lib/Object/Minidump.cpp
@@ -155,41 +155,14 @@ MinidumpFile::create(MemoryBufferRef Source) {
new MinidumpFile(Source, Hdr, *ExpectedStreams, std::move(StreamMap)));
}
-Expected<minidump::Memory64ListHeader> MinidumpFile::getMemoryList64Header() const {
- if (!StreamMap.contains(StreamType::Memory64List))
- return createError("No memory64 list");
-
- Expected<llvm::minidump::Memory64ListHeader> MemoryList64 = getStream<Memory64ListHeader>(StreamType::Memory64List);
- if (!MemoryList64)
- return MemoryList64.takeError();
-
- return MemoryList64;
-}
-
Expected<ArrayRef<MemoryDescriptor_64>> MinidumpFile::getMemory64List() const {
Expected<minidump::Memory64ListHeader> MemoryList64 = getMemoryList64Header();
if (!MemoryList64)
return MemoryList64.takeError();
-
- uint64_t StartOffset = StreamMap.at(StreamType::Memory64List) + sizeof(Memory64ListHeader);
- return getDataSliceAs<minidump::MemoryDescriptor_64>(getData(), StartOffset, sizeof(MemoryDescriptor_64) * MemoryList64->NumberOfMemoryRanges);
-}
-Expected<ArrayRef<uint8_t>>
-MinidumpFile::getRawData(minidump::MemoryDescriptor_64 Desc) const {
- Expected<llvm::minidump::Memory64ListHeader> Memory64Header = getMemoryList64Header();
- if (!Memory64Header)
- return Memory64Header.takeError();
- Expected<ArrayRef<MemoryDescriptor_64>> Memory64List = getMemory64List();
- if (!Memory64List)
- return Memory64List.takeError();
+ std::optional<ArrayRef<uint8_t>> Stream = getRawStream(StreamType::Memory64List);
+ if (!Stream)
+ return createError("No such stream");
- uint64_t RVA = Memory64Header->BaseRVA;
- for (const MemoryDescriptor_64 &InnerDesc : Memory64List.get()) {
- if (Desc.StartOfMemoryRange == InnerDesc.StartOfMemoryRange) {
- return getDataSlice(getData(), RVA, Desc.DataSize);
- }
- }
-
- return createEOFError();
+ return getDataSliceAs<minidump::MemoryDescriptor_64>(*Stream, sizeof(Memory64ListHeader), MemoryList64->NumberOfMemoryRanges);
}
diff --git a/llvm/lib/ObjectYAML/MinidumpYAML.cpp b/llvm/lib/ObjectYAML/MinidumpYAML.cpp
index 1f79f447ffd8b..e0e883470a447 100644
--- a/llvm/lib/ObjectYAML/MinidumpYAML.cpp
+++ b/llvm/lib/ObjectYAML/MinidumpYAML.cpp
@@ -523,9 +523,6 @@ Stream::create(const Directory &StreamDesc, const object::MinidumpFile &File) {
return ExpectedList.takeError();
std::vector<MemoryDescriptor_64> Ranges;
for (const MemoryDescriptor_64 &MD : *ExpectedList) {
- auto ExpectedContent = File.getRawData(MD);
- if (!ExpectedContent)
- return ExpectedContent.takeError();
Ranges.push_back(MD);
}
return std::make_unique<Memory64ListStream>(std::move(Ranges));
>From b3d668f917a36c6dcfdeb146eb9bdc848f8a7fe8 Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalonde at fb.com>
Date: Mon, 29 Jul 2024 13:55:57 -0700
Subject: [PATCH 4/6] Fix yaml2obj minidump emission where I was passing a
stack variable by reference. Change CreateRegionsCache to not double evaluate
Expected<T> as it was causing unchecked to flip back to true instead slotting
into an optional. Uncomment python tests"
---
.../Process/minidump/MinidumpParser.cpp | 28 +-
.../minidump-new/TestMiniDumpNew.py | 885 +++++++++---------
.../minidump-new/linux-x86_64_mem64.dmp | Bin 0 -> 860 bytes
.../minidump-new/linux-x86_64_mem64.yaml | 43 +-
.../minidump-new/relative_module_name.yaml | 8 +-
llvm/include/llvm/ObjectYAML/MinidumpYAML.h | 1 +
llvm/lib/ObjectYAML/MinidumpEmitter.cpp | 17 +-
7 files changed, 498 insertions(+), 484 deletions(-)
create mode 100644 lldb/test/API/functionalities/postmortem/minidump-new/linux-x86_64_mem64.dmp
diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
index 924c54196eb33..eaace69d83a59 100644
--- a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
+++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
@@ -553,14 +553,18 @@ static bool
CreateRegionsCacheFromMemoryList(MinidumpParser &parser,
std::vector<MemoryRegionInfo> ®ions) {
Log *log = GetLog(LLDBLog::Modules);
+ // Cache the expected memory32 into an optional
+ // because double checking the expected triggers the unchecked warning.
+ std::optional<llvm::ArrayRef<MemoryDescriptor>> memory32_list;
auto ExpectedMemory = parser.GetMinidumpFile().getMemoryList();
if (!ExpectedMemory) {
LLDB_LOG_ERROR(log, ExpectedMemory.takeError(),
"Failed to read memory list: {0}");
- return false;
+ } else {
+ memory32_list = *ExpectedMemory;
}
- size_t num_regions = ExpectedMemory->size();
+ size_t num_regions = memory32_list ? memory32_list->size() : 0;
llvm::ArrayRef<uint8_t> data =
parser.GetStream(StreamType::Memory64List);
@@ -575,15 +579,17 @@ CreateRegionsCacheFromMemoryList(MinidumpParser &parser,
}
regions.reserve(num_regions);
- for (const MemoryDescriptor &memory_desc : *ExpectedMemory) {
- if (memory_desc.Memory.DataSize == 0)
- continue;
- MemoryRegionInfo region;
- region.GetRange().SetRangeBase(memory_desc.StartOfMemoryRange);
- region.GetRange().SetByteSize(memory_desc.Memory.DataSize);
- region.SetReadable(MemoryRegionInfo::eYes);
- region.SetMapped(MemoryRegionInfo::eYes);
- regions.push_back(region);
+ if (memory32_list) {
+ for (const MemoryDescriptor &memory_desc : *memory32_list) {
+ if (memory_desc.Memory.DataSize == 0)
+ continue;
+ MemoryRegionInfo region;
+ region.GetRange().SetRangeBase(memory_desc.StartOfMemoryRange);
+ region.GetRange().SetByteSize(memory_desc.Memory.DataSize);
+ region.SetReadable(MemoryRegionInfo::eYes);
+ region.SetMapped(MemoryRegionInfo::eYes);
+ regions.push_back(region);
+ }
}
for (const auto &memory_desc : memory64_list) {
diff --git a/lldb/test/API/functionalities/postmortem/minidump-new/TestMiniDumpNew.py b/lldb/test/API/functionalities/postmortem/minidump-new/TestMiniDumpNew.py
index cd6cc6aaaff19..c7bfc24696609 100644
--- a/lldb/test/API/functionalities/postmortem/minidump-new/TestMiniDumpNew.py
+++ b/lldb/test/API/functionalities/postmortem/minidump-new/TestMiniDumpNew.py
@@ -6,7 +6,7 @@
import lldb
from lldbsuite.test.decorators import *
-from lldbsuite.test.lldbtest import *
+from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
@@ -52,450 +52,449 @@ def check_state(self):
self.dbg.SetOutputFileHandle(None, False)
self.dbg.SetErrorFileHandle(None, False)
- # def test_loadcore_error_status(self):
- # """Test the SBTarget.LoadCore(core, error) overload."""
- # minidump_path = self.getBuildArtifact("linux-x86_64.dmp")
- # self.yaml2obj("linux-x86_64.yaml", minidump_path)
- # self.target = self.dbg.CreateTarget(None)
- # error = lldb.SBError()
- # self.process = self.target.LoadCore(minidump_path, error)
- # self.assertTrue(self.process, PROCESS_IS_VALID)
- # self.assertSuccess(error)
-
- # def test_loadcore_error_status_failure(self):
- # """Test the SBTarget.LoadCore(core, error) overload."""
- # self.target = self.dbg.CreateTarget(None)
- # error = lldb.SBError()
- # self.process = self.target.LoadCore("non-existent.dmp", error)
- # self.assertFalse(self.process, PROCESS_IS_VALID)
- # self.assertTrue(error.Fail())
-
- # def test_process_info_in_minidump(self):
- # """Test that lldb can read the process information from the Minidump."""
- # self.process_from_yaml("linux-x86_64.yaml")
- # self.assertTrue(self.process, PROCESS_IS_VALID)
- # self.assertEqual(self.process.GetNumThreads(), 1)
- # self.assertEqual(self.process.GetProcessID(), self._linux_x86_64_pid)
- # self.check_state()
-
- # def test_memory_region_name(self):
- # self.process_from_yaml("regions-linux-map.yaml")
- # result = lldb.SBCommandReturnObject()
- # addr_region_name_pairs = [
- # ("0x400d9000", "/system/bin/app_process"),
- # ("0x400db000", "/system/bin/app_process"),
- # ("0x400dd000", "/system/bin/linker"),
- # ("0x400ed000", "/system/bin/linker"),
- # ("0x400ee000", "/system/bin/linker"),
- # ("0x400fb000", "/system/lib/liblog.so"),
- # ("0x400fc000", "/system/lib/liblog.so"),
- # ("0x400fd000", "/system/lib/liblog.so"),
- # ("0x400ff000", "/system/lib/liblog.so"),
- # ("0x40100000", "/system/lib/liblog.so"),
- # ("0x40101000", "/system/lib/libc.so"),
- # ("0x40122000", "/system/lib/libc.so"),
- # ("0x40123000", "/system/lib/libc.so"),
- # ("0x40167000", "/system/lib/libc.so"),
- # ("0x40169000", "/system/lib/libc.so"),
- # ]
- # ci = self.dbg.GetCommandInterpreter()
- # for addr, region_name in addr_region_name_pairs:
- # command = "memory region " + addr
- # ci.HandleCommand(command, result, False)
- # message = 'Ensure memory "%s" shows up in output for "%s"' % (
- # region_name,
- # command,
- # )
- # self.assertIn(region_name, result.GetOutput(), message)
-
- # def test_thread_info_in_minidump(self):
- # """Test that lldb can read the thread information from the Minidump."""
- # self.process_from_yaml("linux-x86_64.yaml")
- # self.check_state()
- # # This process crashed due to a segmentation fault in its
- # # one and only thread.
- # self.assertEqual(self.process.GetNumThreads(), 1)
- # thread = self.process.GetThreadAtIndex(0)
- # self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonSignal)
- # stop_description = thread.GetStopDescription(256)
- # self.assertIn("SIGSEGV", stop_description)
-
- # @skipIfLLVMTargetMissing("X86")
- # def test_stack_info_in_minidump(self):
- # """Test that we can see a trivial stack in a breakpad-generated Minidump."""
- # # target create linux-x86_64 -c linux-x86_64.dmp
- # self.dbg.CreateTarget("linux-x86_64")
- # self.target = self.dbg.GetSelectedTarget()
- # self.process = self.target.LoadCore("linux-x86_64.dmp")
- # self.check_state()
- # self.assertEqual(self.process.GetNumThreads(), 1)
- # self.assertEqual(self.process.GetProcessID(), self._linux_x86_64_pid)
- # thread = self.process.GetThreadAtIndex(0)
- # # frame #0: linux-x86_64`crash()
- # # frame #1: linux-x86_64`_start
- # self.assertEqual(thread.GetNumFrames(), 2)
- # frame = thread.GetFrameAtIndex(0)
- # self.assertTrue(frame.IsValid())
- # self.assertTrue(frame.GetModule().IsValid())
- # pc = frame.GetPC()
- # eip = frame.FindRegister("pc")
- # self.assertTrue(eip.IsValid())
- # self.assertEqual(pc, eip.GetValueAsUnsigned())
-
- # def test_snapshot_minidump_dump_requested(self):
- # """Test that if we load a snapshot minidump file (meaning the process
- # did not crash) with exception code "DUMP_REQUESTED" there is no stop reason."""
- # # target create -c linux-x86_64_not_crashed.dmp
- # self.dbg.CreateTarget(None)
- # self.target = self.dbg.GetSelectedTarget()
- # self.process = self.target.LoadCore("linux-x86_64_not_crashed.dmp")
- # self.check_state()
- # self.assertEqual(self.process.GetNumThreads(), 1)
- # thread = self.process.GetThreadAtIndex(0)
- # self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonNone)
- # stop_description = thread.GetStopDescription(256)
- # self.assertEqual(stop_description, "")
-
- # def test_snapshot_minidump_null_exn_code(self):
- # """Test that if we load a snapshot minidump file (meaning the process
- # did not crash) with exception code zero there is no stop reason."""
- # self.process_from_yaml("linux-x86_64_null_signal.yaml")
- # self.check_state()
- # self.assertEqual(self.process.GetNumThreads(), 1)
- # thread = self.process.GetThreadAtIndex(0)
- # self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonNone)
- # stop_description = thread.GetStopDescription(256)
- # self.assertEqual(stop_description, "")
-
- # def check_register_unsigned(self, set, name, expected):
- # reg_value = set.GetChildMemberWithName(name)
- # self.assertTrue(
- # reg_value.IsValid(), 'Verify we have a register named "%s"' % (name)
- # )
- # self.assertEqual(
- # reg_value.GetValueAsUnsigned(),
- # expected,
- # 'Verify "%s" == %i' % (name, expected),
- # )
-
- # def check_register_string_value(self, set, name, expected, format):
- # reg_value = set.GetChildMemberWithName(name)
- # self.assertTrue(
- # reg_value.IsValid(), 'Verify we have a register named "%s"' % (name)
- # )
- # if format is not None:
- # reg_value.SetFormat(format)
- # self.assertEqual(
- # reg_value.GetValue(),
- # expected,
- # 'Verify "%s" has string value "%s"' % (name, expected),
- # )
-
- # def test_arm64_registers(self):
- # """Test ARM64 registers from a breakpad created minidump."""
- # self.process_from_yaml("arm64-macos.yaml")
- # self.check_state()
- # self.assertEqual(self.process.GetNumThreads(), 1)
- # thread = self.process.GetThreadAtIndex(0)
- # self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonNone)
- # stop_description = thread.GetStopDescription(256)
- # self.assertEqual(stop_description, "")
- # registers = thread.GetFrameAtIndex(0).GetRegisters()
- # # Verify the GPR registers are all correct
- # # Verify x0 - x31 register values
- # gpr = registers.GetValueAtIndex(0)
- # for i in range(32):
- # v = i + 1 | i + 2 << 32 | i + 3 << 48
- # w = i + 1
- # self.check_register_unsigned(gpr, "x%i" % (i), v)
- # self.check_register_unsigned(gpr, "w%i" % (i), w)
- # # Verify arg1 - arg8 register values
- # for i in range(1, 9):
- # v = i | i + 1 << 32 | i + 2 << 48
- # self.check_register_unsigned(gpr, "arg%i" % (i), v)
- # i = 29
- # v = i + 1 | i + 2 << 32 | i + 3 << 48
- # self.check_register_unsigned(gpr, "fp", v)
- # i = 30
- # v = i + 1 | i + 2 << 32 | i + 3 << 48
- # self.check_register_unsigned(gpr, "lr", v)
- # i = 31
- # v = i + 1 | i + 2 << 32 | i + 3 << 48
- # self.check_register_unsigned(gpr, "sp", v)
- # self.check_register_unsigned(gpr, "pc", 0x1000)
- # self.check_register_unsigned(gpr, "cpsr", 0x11223344)
- # self.check_register_unsigned(gpr, "psr", 0x11223344)
-
- # # Verify the FPR registers are all correct
- # fpr = registers.GetValueAtIndex(1)
- # for i in range(32):
- # v = "0x"
- # d = "0x"
- # s = "0x"
- # h = "0x"
- # for j in range(i + 15, i - 1, -1):
- # v += "%2.2x" % (j)
- # for j in range(i + 7, i - 1, -1):
- # d += "%2.2x" % (j)
- # for j in range(i + 3, i - 1, -1):
- # s += "%2.2x" % (j)
- # for j in range(i + 1, i - 1, -1):
- # h += "%2.2x" % (j)
- # self.check_register_string_value(fpr, "v%i" % (i), v, lldb.eFormatHex)
- # self.check_register_string_value(fpr, "d%i" % (i), d, lldb.eFormatHex)
- # self.check_register_string_value(fpr, "s%i" % (i), s, lldb.eFormatHex)
- # self.check_register_string_value(fpr, "h%i" % (i), h, lldb.eFormatHex)
- # self.check_register_unsigned(gpr, "fpsr", 0x55667788)
- # self.check_register_unsigned(gpr, "fpcr", 0x99AABBCC)
-
- # def verify_arm_registers(self, apple=False):
- # """
- # Verify values of all ARM registers from a breakpad created
- # minidump.
- # """
- # if apple:
- # self.process_from_yaml("arm-macos.yaml")
- # else:
- # self.process_from_yaml("arm-linux.yaml")
- # self.check_state()
- # self.assertEqual(self.process.GetNumThreads(), 1)
- # thread = self.process.GetThreadAtIndex(0)
- # self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonNone)
- # stop_description = thread.GetStopDescription(256)
- # self.assertEqual(stop_description, "")
- # registers = thread.GetFrameAtIndex(0).GetRegisters()
- # # Verify the GPR registers are all correct
- # # Verify x0 - x31 register values
- # gpr = registers.GetValueAtIndex(0)
- # for i in range(1, 16):
- # self.check_register_unsigned(gpr, "r%i" % (i), i + 1)
- # # Verify arg1 - arg4 register values
- # for i in range(1, 5):
- # self.check_register_unsigned(gpr, "arg%i" % (i), i)
- # if apple:
- # self.check_register_unsigned(gpr, "fp", 0x08)
- # else:
- # self.check_register_unsigned(gpr, "fp", 0x0C)
- # self.check_register_unsigned(gpr, "lr", 0x0F)
- # self.check_register_unsigned(gpr, "sp", 0x0E)
- # self.check_register_unsigned(gpr, "pc", 0x10)
- # self.check_register_unsigned(gpr, "cpsr", 0x11223344)
-
- # # Verify the FPR registers are all correct
- # fpr = registers.GetValueAtIndex(1)
- # # Check d0 - d31
- # self.check_register_unsigned(gpr, "fpscr", 0x55667788AABBCCDD)
- # for i in range(32):
- # value = (i + 1) | (i + 1) << 8 | (i + 1) << 32 | (i + 1) << 48
- # self.check_register_unsigned(fpr, "d%i" % (i), value)
- # # Check s0 - s31
- # for i in range(32):
- # i_val = (i >> 1) + 1
- # if i & 1:
- # value = "%#8.8x" % (i_val | i_val << 16)
- # else:
- # value = "%#8.8x" % (i_val | i_val << 8)
- # self.check_register_string_value(fpr, "s%i" % (i), value, lldb.eFormatHex)
- # # Check q0 - q15
- # for i in range(15):
- # a = i * 2 + 1
- # b = a + 1
- # value = (
- # "0x00%2.2x00%2.2x0000%2.2x%2.2x" "00%2.2x00%2.2x0000%2.2x%2.2x"
- # ) % (b, b, b, b, a, a, a, a)
- # self.check_register_string_value(fpr, "q%i" % (i), value, lldb.eFormatHex)
-
- # def test_linux_arm_registers(self):
- # """Test Linux ARM registers from a breakpad created minidump.
-
- # The frame pointer is R11 for linux.
- # """
- # self.verify_arm_registers(apple=False)
-
- # def test_apple_arm_registers(self):
- # """Test Apple ARM registers from a breakpad created minidump.
-
- # The frame pointer is R7 for linux.
- # """
- # self.verify_arm_registers(apple=True)
-
- # def do_test_deeper_stack(self, binary, core, pid):
- # target = self.dbg.CreateTarget(binary)
- # process = target.LoadCore(core)
- # thread = process.GetThreadAtIndex(0)
-
- # self.assertEqual(process.GetProcessID(), pid)
-
- # expected_stack = {1: "bar", 2: "foo", 3: "_start"}
- # self.assertGreaterEqual(thread.GetNumFrames(), len(expected_stack))
- # for index, name in expected_stack.items():
- # frame = thread.GetFrameAtIndex(index)
- # self.assertTrue(frame.IsValid())
- # function_name = frame.GetFunctionName()
- # self.assertIn(name, function_name)
-
- # @skipIfLLVMTargetMissing("X86")
- # def test_deeper_stack_in_minidump(self):
- # """Test that we can examine a more interesting stack in a Minidump."""
- # # Launch with the Minidump, and inspect the stack.
- # # target create linux-x86_64_not_crashed -c linux-x86_64_not_crashed.dmp
- # self.do_test_deeper_stack(
- # "linux-x86_64_not_crashed",
- # "linux-x86_64_not_crashed.dmp",
- # self._linux_x86_64_not_crashed_pid,
- # )
-
- # def do_change_pid_in_minidump(self, core, newcore, offset, oldpid, newpid):
- # """This assumes that the minidump is breakpad generated on Linux -
- # meaning that the PID in the file will be an ascii string part of
- # /proc/PID/status which is written in the file
- # """
- # shutil.copyfile(core, newcore)
- # with open(newcore, "rb+") as f:
- # f.seek(offset)
- # currentpid = f.read(5).decode("utf-8")
- # self.assertEqual(currentpid, oldpid)
-
- # f.seek(offset)
- # if len(newpid) < len(oldpid):
- # newpid += " " * (len(oldpid) - len(newpid))
- # newpid += "\n"
- # f.write(newpid.encode("utf-8"))
-
- # @skipIfLLVMTargetMissing("X86")
- # def test_deeper_stack_in_minidump_with_same_pid_running(self):
- # """Test that we read the information from the core correctly even if we
- # have a running process with the same PID"""
- # new_core = self.getBuildArtifact("linux-x86_64_not_crashed-pid.dmp")
- # self.do_change_pid_in_minidump(
- # "linux-x86_64_not_crashed.dmp",
- # new_core,
- # self._linux_x86_64_not_crashed_pid_offset,
- # str(self._linux_x86_64_not_crashed_pid),
- # str(os.getpid()),
- # )
- # self.do_test_deeper_stack("linux-x86_64_not_crashed", new_core, os.getpid())
-
- # @skipIfLLVMTargetMissing("X86")
- # def test_two_cores_same_pid(self):
- # """Test that we handle the situation if we have two core files with the same PID"""
- # new_core = self.getBuildArtifact("linux-x86_64_not_crashed-pid.dmp")
- # self.do_change_pid_in_minidump(
- # "linux-x86_64_not_crashed.dmp",
- # new_core,
- # self._linux_x86_64_not_crashed_pid_offset,
- # str(self._linux_x86_64_not_crashed_pid),
- # str(self._linux_x86_64_pid),
- # )
- # self.do_test_deeper_stack(
- # "linux-x86_64_not_crashed", new_core, self._linux_x86_64_pid
- # )
- # self.test_stack_info_in_minidump()
-
- # @skipIfLLVMTargetMissing("X86")
- # def test_local_variables_in_minidump(self):
- # """Test that we can examine local variables in a Minidump."""
- # # Launch with the Minidump, and inspect a local variable.
- # # target create linux-x86_64_not_crashed -c linux-x86_64_not_crashed.dmp
- # self.target = self.dbg.CreateTarget("linux-x86_64_not_crashed")
- # self.process = self.target.LoadCore("linux-x86_64_not_crashed.dmp")
- # self.check_state()
- # thread = self.process.GetThreadAtIndex(0)
- # 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"""
- # self.process_from_yaml("regions-linux-map.yaml")
- # 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)
-
- # @skipIfLLVMTargetMissing("X86")
- # def test_minidump_sysroot(self):
- # """Test that lldb can find a module referenced in an i386 linux minidump using the sysroot."""
-
- # # Copy linux-x86_64 executable to tmp_sysroot/temp/test/ (since it was compiled as
- # # /tmp/test/linux-x86_64)
- # tmp_sysroot = os.path.join(self.getBuildDir(), "lldb_i386_mock_sysroot")
- # executable = os.path.join(tmp_sysroot, "tmp", "test", "linux-x86_64")
- # exe_dir = os.path.dirname(executable)
- # lldbutil.mkdir_p(exe_dir)
- # shutil.copyfile("linux-x86_64", executable)
-
- # # Set sysroot and load core
- # self.runCmd("platform select remote-linux --sysroot '%s'" % tmp_sysroot)
- # self.process_from_yaml("linux-x86_64.yaml")
- # self.check_state()
-
- # # Check that we loaded the module from the sysroot
- # self.assertEqual(self.target.GetNumModules(), 1)
- # module = self.target.GetModuleAtIndex(0)
- # spec_dir_norm = os.path.normcase(module.GetFileSpec().GetDirectory())
- # exe_dir_norm = os.path.normcase(exe_dir)
- # self.assertEqual(spec_dir_norm, exe_dir_norm)
+ def test_loadcore_error_status(self):
+ """Test the SBTarget.LoadCore(core, error) overload."""
+ minidump_path = self.getBuildArtifact("linux-x86_64.dmp")
+ self.yaml2obj("linux-x86_64.yaml", minidump_path)
+ self.target = self.dbg.CreateTarget(None)
+ error = lldb.SBError()
+ self.process = self.target.LoadCore(minidump_path, error)
+ self.assertTrue(self.process, PROCESS_IS_VALID)
+ self.assertSuccess(error)
+
+ def test_loadcore_error_status_failure(self):
+ """Test the SBTarget.LoadCore(core, error) overload."""
+ self.target = self.dbg.CreateTarget(None)
+ error = lldb.SBError()
+ self.process = self.target.LoadCore("non-existent.dmp", error)
+ self.assertFalse(self.process, PROCESS_IS_VALID)
+ self.assertTrue(error.Fail())
+
+ def test_process_info_in_minidump(self):
+ """Test that lldb can read the process information from the Minidump."""
+ self.process_from_yaml("linux-x86_64.yaml")
+ self.assertTrue(self.process, PROCESS_IS_VALID)
+ self.assertEqual(self.process.GetNumThreads(), 1)
+ self.assertEqual(self.process.GetProcessID(), self._linux_x86_64_pid)
+ self.check_state()
+
+ def test_memory_region_name(self):
+ self.process_from_yaml("regions-linux-map.yaml")
+ result = lldb.SBCommandReturnObject()
+ addr_region_name_pairs = [
+ ("0x400d9000", "/system/bin/app_process"),
+ ("0x400db000", "/system/bin/app_process"),
+ ("0x400dd000", "/system/bin/linker"),
+ ("0x400ed000", "/system/bin/linker"),
+ ("0x400ee000", "/system/bin/linker"),
+ ("0x400fb000", "/system/lib/liblog.so"),
+ ("0x400fc000", "/system/lib/liblog.so"),
+ ("0x400fd000", "/system/lib/liblog.so"),
+ ("0x400ff000", "/system/lib/liblog.so"),
+ ("0x40100000", "/system/lib/liblog.so"),
+ ("0x40101000", "/system/lib/libc.so"),
+ ("0x40122000", "/system/lib/libc.so"),
+ ("0x40123000", "/system/lib/libc.so"),
+ ("0x40167000", "/system/lib/libc.so"),
+ ("0x40169000", "/system/lib/libc.so"),
+ ]
+ ci = self.dbg.GetCommandInterpreter()
+ for addr, region_name in addr_region_name_pairs:
+ command = "memory region " + addr
+ ci.HandleCommand(command, result, False)
+ message = 'Ensure memory "%s" shows up in output for "%s"' % (
+ region_name,
+ command,
+ )
+ self.assertIn(region_name, result.GetOutput(), message)
+
+ def test_thread_info_in_minidump(self):
+ """Test that lldb can read the thread information from the Minidump."""
+ self.process_from_yaml("linux-x86_64.yaml")
+ self.check_state()
+ # This process crashed due to a segmentation fault in its
+ # one and only thread.
+ self.assertEqual(self.process.GetNumThreads(), 1)
+ thread = self.process.GetThreadAtIndex(0)
+ self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonSignal)
+ stop_description = thread.GetStopDescription(256)
+ self.assertIn("SIGSEGV", stop_description)
+
+ @skipIfLLVMTargetMissing("X86")
+ def test_stack_info_in_minidump(self):
+ """Test that we can see a trivial stack in a breakpad-generated Minidump."""
+ # target create linux-x86_64 -c linux-x86_64.dmp
+ self.dbg.CreateTarget("linux-x86_64")
+ self.target = self.dbg.GetSelectedTarget()
+ self.process = self.target.LoadCore("linux-x86_64.dmp")
+ self.check_state()
+ self.assertEqual(self.process.GetNumThreads(), 1)
+ self.assertEqual(self.process.GetProcessID(), self._linux_x86_64_pid)
+ thread = self.process.GetThreadAtIndex(0)
+ # frame #0: linux-x86_64`crash()
+ # frame #1: linux-x86_64`_start
+ self.assertEqual(thread.GetNumFrames(), 2)
+ frame = thread.GetFrameAtIndex(0)
+ self.assertTrue(frame.IsValid())
+ self.assertTrue(frame.GetModule().IsValid())
+ pc = frame.GetPC()
+ eip = frame.FindRegister("pc")
+ self.assertTrue(eip.IsValid())
+ self.assertEqual(pc, eip.GetValueAsUnsigned())
+
+ def test_snapshot_minidump_dump_requested(self):
+ """Test that if we load a snapshot minidump file (meaning the process
+ did not crash) with exception code "DUMP_REQUESTED" there is no stop reason."""
+ # target create -c linux-x86_64_not_crashed.dmp
+ self.dbg.CreateTarget(None)
+ self.target = self.dbg.GetSelectedTarget()
+ self.process = self.target.LoadCore("linux-x86_64_not_crashed.dmp")
+ self.check_state()
+ self.assertEqual(self.process.GetNumThreads(), 1)
+ thread = self.process.GetThreadAtIndex(0)
+ self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonNone)
+ stop_description = thread.GetStopDescription(256)
+ self.assertEqual(stop_description, "")
+
+ def test_snapshot_minidump_null_exn_code(self):
+ """Test that if we load a snapshot minidump file (meaning the process
+ did not crash) with exception code zero there is no stop reason."""
+ self.process_from_yaml("linux-x86_64_null_signal.yaml")
+ self.check_state()
+ self.assertEqual(self.process.GetNumThreads(), 1)
+ thread = self.process.GetThreadAtIndex(0)
+ self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonNone)
+ stop_description = thread.GetStopDescription(256)
+ self.assertEqual(stop_description, "")
+
+ def check_register_unsigned(self, set, name, expected):
+ reg_value = set.GetChildMemberWithName(name)
+ self.assertTrue(
+ reg_value.IsValid(), 'Verify we have a register named "%s"' % (name)
+ )
+ self.assertEqual(
+ reg_value.GetValueAsUnsigned(),
+ expected,
+ 'Verify "%s" == %i' % (name, expected),
+ )
+
+ def check_register_string_value(self, set, name, expected, format):
+ reg_value = set.GetChildMemberWithName(name)
+ self.assertTrue(
+ reg_value.IsValid(), 'Verify we have a register named "%s"' % (name)
+ )
+ if format is not None:
+ reg_value.SetFormat(format)
+ self.assertEqual(
+ reg_value.GetValue(),
+ expected,
+ 'Verify "%s" has string value "%s"' % (name, expected),
+ )
+
+ def test_arm64_registers(self):
+ """Test ARM64 registers from a breakpad created minidump."""
+ self.process_from_yaml("arm64-macos.yaml")
+ self.check_state()
+ self.assertEqual(self.process.GetNumThreads(), 1)
+ thread = self.process.GetThreadAtIndex(0)
+ self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonNone)
+ stop_description = thread.GetStopDescription(256)
+ self.assertEqual(stop_description, "")
+ registers = thread.GetFrameAtIndex(0).GetRegisters()
+ # Verify the GPR registers are all correct
+ # Verify x0 - x31 register values
+ gpr = registers.GetValueAtIndex(0)
+ for i in range(32):
+ v = i + 1 | i + 2 << 32 | i + 3 << 48
+ w = i + 1
+ self.check_register_unsigned(gpr, "x%i" % (i), v)
+ self.check_register_unsigned(gpr, "w%i" % (i), w)
+ # Verify arg1 - arg8 register values
+ for i in range(1, 9):
+ v = i | i + 1 << 32 | i + 2 << 48
+ self.check_register_unsigned(gpr, "arg%i" % (i), v)
+ i = 29
+ v = i + 1 | i + 2 << 32 | i + 3 << 48
+ self.check_register_unsigned(gpr, "fp", v)
+ i = 30
+ v = i + 1 | i + 2 << 32 | i + 3 << 48
+ self.check_register_unsigned(gpr, "lr", v)
+ i = 31
+ v = i + 1 | i + 2 << 32 | i + 3 << 48
+ self.check_register_unsigned(gpr, "sp", v)
+ self.check_register_unsigned(gpr, "pc", 0x1000)
+ self.check_register_unsigned(gpr, "cpsr", 0x11223344)
+ self.check_register_unsigned(gpr, "psr", 0x11223344)
+
+ # Verify the FPR registers are all correct
+ fpr = registers.GetValueAtIndex(1)
+ for i in range(32):
+ v = "0x"
+ d = "0x"
+ s = "0x"
+ h = "0x"
+ for j in range(i + 15, i - 1, -1):
+ v += "%2.2x" % (j)
+ for j in range(i + 7, i - 1, -1):
+ d += "%2.2x" % (j)
+ for j in range(i + 3, i - 1, -1):
+ s += "%2.2x" % (j)
+ for j in range(i + 1, i - 1, -1):
+ h += "%2.2x" % (j)
+ self.check_register_string_value(fpr, "v%i" % (i), v, lldb.eFormatHex)
+ self.check_register_string_value(fpr, "d%i" % (i), d, lldb.eFormatHex)
+ self.check_register_string_value(fpr, "s%i" % (i), s, lldb.eFormatHex)
+ self.check_register_string_value(fpr, "h%i" % (i), h, lldb.eFormatHex)
+ self.check_register_unsigned(gpr, "fpsr", 0x55667788)
+ self.check_register_unsigned(gpr, "fpcr", 0x99AABBCC)
+
+ def verify_arm_registers(self, apple=False):
+ """
+ Verify values of all ARM registers from a breakpad created
+ minidump.
+ """
+ if apple:
+ self.process_from_yaml("arm-macos.yaml")
+ else:
+ self.process_from_yaml("arm-linux.yaml")
+ self.check_state()
+ self.assertEqual(self.process.GetNumThreads(), 1)
+ thread = self.process.GetThreadAtIndex(0)
+ self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonNone)
+ stop_description = thread.GetStopDescription(256)
+ self.assertEqual(stop_description, "")
+ registers = thread.GetFrameAtIndex(0).GetRegisters()
+ # Verify the GPR registers are all correct
+ # Verify x0 - x31 register values
+ gpr = registers.GetValueAtIndex(0)
+ for i in range(1, 16):
+ self.check_register_unsigned(gpr, "r%i" % (i), i + 1)
+ # Verify arg1 - arg4 register values
+ for i in range(1, 5):
+ self.check_register_unsigned(gpr, "arg%i" % (i), i)
+ if apple:
+ self.check_register_unsigned(gpr, "fp", 0x08)
+ else:
+ self.check_register_unsigned(gpr, "fp", 0x0C)
+ self.check_register_unsigned(gpr, "lr", 0x0F)
+ self.check_register_unsigned(gpr, "sp", 0x0E)
+ self.check_register_unsigned(gpr, "pc", 0x10)
+ self.check_register_unsigned(gpr, "cpsr", 0x11223344)
+
+ # Verify the FPR registers are all correct
+ fpr = registers.GetValueAtIndex(1)
+ # Check d0 - d31
+ self.check_register_unsigned(gpr, "fpscr", 0x55667788AABBCCDD)
+ for i in range(32):
+ value = (i + 1) | (i + 1) << 8 | (i + 1) << 32 | (i + 1) << 48
+ self.check_register_unsigned(fpr, "d%i" % (i), value)
+ # Check s0 - s31
+ for i in range(32):
+ i_val = (i >> 1) + 1
+ if i & 1:
+ value = "%#8.8x" % (i_val | i_val << 16)
+ else:
+ value = "%#8.8x" % (i_val | i_val << 8)
+ self.check_register_string_value(fpr, "s%i" % (i), value, lldb.eFormatHex)
+ # Check q0 - q15
+ for i in range(15):
+ a = i * 2 + 1
+ b = a + 1
+ value = (
+ "0x00%2.2x00%2.2x0000%2.2x%2.2x" "00%2.2x00%2.2x0000%2.2x%2.2x"
+ ) % (b, b, b, b, a, a, a, a)
+ self.check_register_string_value(fpr, "q%i" % (i), value, lldb.eFormatHex)
+
+ def test_linux_arm_registers(self):
+ """Test Linux ARM registers from a breakpad created minidump.
+
+ The frame pointer is R11 for linux.
+ """
+ self.verify_arm_registers(apple=False)
+
+ def test_apple_arm_registers(self):
+ """Test Apple ARM registers from a breakpad created minidump.
+
+ The frame pointer is R7 for linux.
+ """
+ self.verify_arm_registers(apple=True)
+
+ def do_test_deeper_stack(self, binary, core, pid):
+ target = self.dbg.CreateTarget(binary)
+ process = target.LoadCore(core)
+ thread = process.GetThreadAtIndex(0)
+
+ self.assertEqual(process.GetProcessID(), pid)
+
+ expected_stack = {1: "bar", 2: "foo", 3: "_start"}
+ self.assertGreaterEqual(thread.GetNumFrames(), len(expected_stack))
+ for index, name in expected_stack.items():
+ frame = thread.GetFrameAtIndex(index)
+ self.assertTrue(frame.IsValid())
+ function_name = frame.GetFunctionName()
+ self.assertIn(name, function_name)
+
+ @skipIfLLVMTargetMissing("X86")
+ def test_deeper_stack_in_minidump(self):
+ """Test that we can examine a more interesting stack in a Minidump."""
+ # Launch with the Minidump, and inspect the stack.
+ # target create linux-x86_64_not_crashed -c linux-x86_64_not_crashed.dmp
+ self.do_test_deeper_stack(
+ "linux-x86_64_not_crashed",
+ "linux-x86_64_not_crashed.dmp",
+ self._linux_x86_64_not_crashed_pid,
+ )
+
+ def do_change_pid_in_minidump(self, core, newcore, offset, oldpid, newpid):
+ """This assumes that the minidump is breakpad generated on Linux -
+ meaning that the PID in the file will be an ascii string part of
+ /proc/PID/status which is written in the file
+ """
+ shutil.copyfile(core, newcore)
+ with open(newcore, "rb+") as f:
+ f.seek(offset)
+ currentpid = f.read(5).decode("utf-8")
+ self.assertEqual(currentpid, oldpid)
+
+ f.seek(offset)
+ if len(newpid) < len(oldpid):
+ newpid += " " * (len(oldpid) - len(newpid))
+ newpid += "\n"
+ f.write(newpid.encode("utf-8"))
+
+ @skipIfLLVMTargetMissing("X86")
+ def test_deeper_stack_in_minidump_with_same_pid_running(self):
+ """Test that we read the information from the core correctly even if we
+ have a running process with the same PID"""
+ new_core = self.getBuildArtifact("linux-x86_64_not_crashed-pid.dmp")
+ self.do_change_pid_in_minidump(
+ "linux-x86_64_not_crashed.dmp",
+ new_core,
+ self._linux_x86_64_not_crashed_pid_offset,
+ str(self._linux_x86_64_not_crashed_pid),
+ str(os.getpid()),
+ )
+ self.do_test_deeper_stack("linux-x86_64_not_crashed", new_core, os.getpid())
+
+ @skipIfLLVMTargetMissing("X86")
+ def test_two_cores_same_pid(self):
+ """Test that we handle the situation if we have two core files with the same PID"""
+ new_core = self.getBuildArtifact("linux-x86_64_not_crashed-pid.dmp")
+ self.do_change_pid_in_minidump(
+ "linux-x86_64_not_crashed.dmp",
+ new_core,
+ self._linux_x86_64_not_crashed_pid_offset,
+ str(self._linux_x86_64_not_crashed_pid),
+ str(self._linux_x86_64_pid),
+ )
+ self.do_test_deeper_stack(
+ "linux-x86_64_not_crashed", new_core, self._linux_x86_64_pid
+ )
+ self.test_stack_info_in_minidump()
+
+ @skipIfLLVMTargetMissing("X86")
+ def test_local_variables_in_minidump(self):
+ """Test that we can examine local variables in a Minidump."""
+ # Launch with the Minidump, and inspect a local variable.
+ # target create linux-x86_64_not_crashed -c linux-x86_64_not_crashed.dmp
+ self.target = self.dbg.CreateTarget("linux-x86_64_not_crashed")
+ self.process = self.target.LoadCore("linux-x86_64_not_crashed.dmp")
+ self.check_state()
+ thread = self.process.GetThreadAtIndex(0)
+ 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"""
+ self.process_from_yaml("regions-linux-map.yaml")
+ 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)
+
+ @skipIfLLVMTargetMissing("X86")
+ def test_minidump_sysroot(self):
+ """Test that lldb can find a module referenced in an i386 linux minidump using the sysroot."""
+
+ # Copy linux-x86_64 executable to tmp_sysroot/temp/test/ (since it was compiled as
+ # /tmp/test/linux-x86_64)
+ tmp_sysroot = os.path.join(self.getBuildDir(), "lldb_i386_mock_sysroot")
+ executable = os.path.join(tmp_sysroot, "tmp", "test", "linux-x86_64")
+ exe_dir = os.path.dirname(executable)
+ lldbutil.mkdir_p(exe_dir)
+ shutil.copyfile("linux-x86_64", executable)
+
+ # Set sysroot and load core
+ self.runCmd("platform select remote-linux --sysroot '%s'" % tmp_sysroot)
+ self.process_from_yaml("linux-x86_64.yaml")
+ self.check_state()
+
+ # Check that we loaded the module from the sysroot
+ self.assertEqual(self.target.GetNumModules(), 1)
+ module = self.target.GetModuleAtIndex(0)
+ spec_dir_norm = os.path.normcase(module.GetFileSpec().GetDirectory())
+ exe_dir_norm = os.path.normcase(exe_dir)
+ self.assertEqual(spec_dir_norm, exe_dir_norm)
def test_minidump_memory64list(self):
"""Test that lldb can read from the memory64list in a minidump."""
self.process_from_yaml("linux-x86_64_mem64.yaml")
- self.check_state()
region_count = 1
region_info_list = self.process.GetMemoryRegions()
@@ -503,7 +502,7 @@ def test_minidump_memory64list(self):
region = lldb.SBMemoryRegionInfo()
self.assertTrue(region_info_list.GetMemoryRegionAtIndex(0, region))
- self.assertEqual(region.GetRegionBase(), 0x07000FFD4BC15080)
- self.assertTrue(region.GetRegionEnd(), 0x07000FFD4BC15080 + 8)
+ self.assertEqual(region.GetRegionBase(), 0x7FFF12A84030)
+ self.assertTrue(region.GetRegionEnd(), 0x2FD0)
diff --git a/lldb/test/API/functionalities/postmortem/minidump-new/linux-x86_64_mem64.dmp b/lldb/test/API/functionalities/postmortem/minidump-new/linux-x86_64_mem64.dmp
new file mode 100644
index 0000000000000000000000000000000000000000..a1069ef45ad3543bcc2862fa8699b239c2fefa8e
GIT binary patch
literal 860
zcmeZu at eP=~oPmLffq_8*h|vKvP{0I;Er6I4h&$LA7;J!oj6nA8X&OKhKga<}UjP~o
zqDckp3<6*+|AByk0YpLospb$;zrkUJ(EoZus>qiQxUf8W7Y)rP-({mZDG7lJ|1VOk
XVGIm6(&az?t7l*|fTp7h`VdnAg=Zxs
literal 0
HcmV?d00001
diff --git a/lldb/test/API/functionalities/postmortem/minidump-new/linux-x86_64_mem64.yaml b/lldb/test/API/functionalities/postmortem/minidump-new/linux-x86_64_mem64.yaml
index 698ba90329a4e..2c0687eeaaeb7 100644
--- a/lldb/test/API/functionalities/postmortem/minidump-new/linux-x86_64_mem64.yaml
+++ b/lldb/test/API/functionalities/postmortem/minidump-new/linux-x86_64_mem64.yaml
@@ -1,23 +1,36 @@
--- !minidump
Streams:
+ - Type: SystemInfo
+ Processor Arch: AMD64
+ Processor Level: 6
+ Processor Revision: 15876
+ Number of Processors: 40
+ Platform ID: Linux
+ CSD Version: 'Linux 3.13.0-91-generic'
+ CPU:
+ Vendor ID: GenuineIntel
+ Version Info: 0x00000000
+ Feature Info: 0x00000000
+ - Type: LinuxProcStatus
+ Text: |
+ Name: linux-x86_64
+ State: t (tracing stop)
+ Tgid: 29917
+ Ngid: 0
+ Pid: 29917
+ PPid: 29370
+ TracerPid: 29918
+ Uid: 1001 1001 1001 1001
+ Gid: 1001 1001 1001 1001
- Type: ThreadList
Threads:
- - Thread Id: 0x000074DD
- Context: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B0010000000000033000000000000000000000002020100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040109600000000000100000000000000000000000000000068E7D0C8FF7F000068E7D0C8FF7F000097E6D0C8FF7F000010109600000000000000000000000000020000000000000088E4D0C8FF7F0000603FFF85C77F0000F00340000000000080E7D0C8FF7F000000000000000000000000000000000000E0034000000000007F0300000000000000000000000000000000000000000000801F0000FFFF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF252525252525252525252525252525250000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000FF00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+ - Thread Id: 0x2896BB
+ Context: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000700100000000000FFFFFFFF0000FFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B040A812FF7F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000050D0A75BBA7F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Stack:
- Start of Memory Range: 0x00007FFFC8D0E000
- Content: DEADBEEFBAADF00D
- - Type: ModuleList
- Modules:
- - Base of Image: 0x0000000000400000
- Size of Image: 0x00001000
- Module Name: '/tmp/test/linux-x86_64'
- CodeView Record: 4C457042E35C283BC327C28762DB788BF5A4078BE2351448
+ Start of Memory Range: 0x0
+ Content: ''
- Type: Memory64List
- Number of Memory Ranges: 1
- Base RVA: 0x07000FFD4BC15080
Memory Ranges:
- - Start of Memory Range: 0x07000FFD4BC15080
- Content: 80000008
-
+ - Start of memory range: 0x7FFF12A84030
+ Data Size: 0x2FD0
...
diff --git a/lldb/test/API/functionalities/postmortem/minidump-new/relative_module_name.yaml b/lldb/test/API/functionalities/postmortem/minidump-new/relative_module_name.yaml
index 23f2b49028039..ecab417f9cd41 100644
--- a/lldb/test/API/functionalities/postmortem/minidump-new/relative_module_name.yaml
+++ b/lldb/test/API/functionalities/postmortem/minidump-new/relative_module_name.yaml
@@ -1,15 +1,15 @@
--- !minidump
-Streams:
+Streams:
- Type: SystemInfo
Processor Arch: AMD64
Platform ID: Linux
CSD Version: '15E216'
- CPU:
- Vendor ID: GenuineIntel
+ CPU:
+ Vendor ID: GenuineIntelâ€
Version Info: 0x00000000
Feature Info: 0x00000000
- Type: ModuleList
- Modules:
+ Modules:
- Base of Image: 0x0000000000001000
Size of Image: 0x00001000
Module Name: 'file-with-a-name-unlikely-to-exist-in-the-current-directory.so'
diff --git a/llvm/include/llvm/ObjectYAML/MinidumpYAML.h b/llvm/include/llvm/ObjectYAML/MinidumpYAML.h
index 44500f5678803..51fc6cc3bea89 100644
--- a/llvm/include/llvm/ObjectYAML/MinidumpYAML.h
+++ b/llvm/include/llvm/ObjectYAML/MinidumpYAML.h
@@ -109,6 +109,7 @@ using MemoryListStream = detail::ListStream<detail::ParsedMemoryDescriptor>;
struct Memory64ListStream : public Stream {
std::vector<minidump::MemoryDescriptor_64> Entries;
yaml::BinaryRef Content;
+ minidump::Memory64ListHeader Header;
Memory64ListStream()
: Stream(StreamKind::Memory64List, minidump::StreamType::Memory64List) {}
diff --git a/llvm/lib/ObjectYAML/MinidumpEmitter.cpp b/llvm/lib/ObjectYAML/MinidumpEmitter.cpp
index 95f36b0f9ce91..f992c4e3bde76 100644
--- a/llvm/lib/ObjectYAML/MinidumpEmitter.cpp
+++ b/llvm/lib/ObjectYAML/MinidumpEmitter.cpp
@@ -136,17 +136,12 @@ static size_t layout(BlobAllocator &File, MinidumpYAML::ExceptionStream &S) {
return DataEnd;
}
-static size_t layout(BlobAllocator &File, MinidumpYAML::Memory64ListStream &S) {
- size_t DataEnd = File.tell();
+static void layout(BlobAllocator &File, MinidumpYAML::Memory64ListStream &S) {
size_t BaseRVA = File.tell() + sizeof(minidump::Memory64ListHeader);
- size_t NumStreams = S.Entries.size();
- llvm::minidump::Memory64ListHeader Header;
- Header.BaseRVA = BaseRVA;
- Header.NumberOfMemoryRanges = NumStreams;
- DataEnd += File.allocateObject(Header);
- DataEnd += File.allocateArray(ArrayRef(S.Entries));
-
- return DataEnd;
+ S.Header.BaseRVA = BaseRVA;
+ S.Header.NumberOfMemoryRanges = S.Entries.size();
+ File.allocateObject(S.Header);
+ File.allocateArray(ArrayRef(S.Entries));
}
static void layout(BlobAllocator &File, MemoryListStream::entry_type &Range) {
@@ -204,7 +199,7 @@ static Directory layout(BlobAllocator &File, Stream &S) {
DataEnd = layout(File, cast<MemoryListStream>(S));
break;
case Stream::StreamKind::Memory64List:
- DataEnd = layout(File, cast<Memory64ListStream>(S));
+ layout(File, cast<Memory64ListStream>(S));
break;
case Stream::StreamKind::ModuleList:
DataEnd = layout(File, cast<ModuleListStream>(S));
>From a1bb644228596b4c04b2be89982e907258a77267 Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalonde at fb.com>
Date: Mon, 29 Jul 2024 13:58:22 -0700
Subject: [PATCH 5/6] Run C++ and Python formatters.
---
.../Plugins/Process/minidump/MinidumpParser.cpp | 8 ++++----
.../postmortem/minidump-new/TestMiniDumpNew.py | 4 +---
llvm/include/llvm/Object/Minidump.h | 7 ++++---
llvm/include/llvm/ObjectYAML/MinidumpYAML.h | 17 ++++++++++-------
llvm/lib/Object/Minidump.cpp | 13 ++++++++-----
llvm/lib/ObjectYAML/MinidumpYAML.cpp | 3 ++-
6 files changed, 29 insertions(+), 23 deletions(-)
diff --git a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
index eaace69d83a59..7e19acd3d0834 100644
--- a/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
+++ b/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp
@@ -571,11 +571,11 @@ CreateRegionsCacheFromMemoryList(MinidumpParser &parser,
llvm::ArrayRef<MinidumpMemoryDescriptor64> memory64_list;
if (!data.empty()) {
- uint64_t base_rva;
- std::tie(memory64_list, base_rva) =
- MinidumpMemoryDescriptor64::ParseMemory64List(data);
+ uint64_t base_rva;
+ std::tie(memory64_list, base_rva) =
+ MinidumpMemoryDescriptor64::ParseMemory64List(data);
- num_regions += memory64_list.size();
+ num_regions += memory64_list.size();
}
regions.reserve(num_regions);
diff --git a/lldb/test/API/functionalities/postmortem/minidump-new/TestMiniDumpNew.py b/lldb/test/API/functionalities/postmortem/minidump-new/TestMiniDumpNew.py
index c7bfc24696609..03f4de4120da4 100644
--- a/lldb/test/API/functionalities/postmortem/minidump-new/TestMiniDumpNew.py
+++ b/lldb/test/API/functionalities/postmortem/minidump-new/TestMiniDumpNew.py
@@ -6,7 +6,7 @@
import lldb
from lldbsuite.test.decorators import *
-from lldbsuite.test.lldbtest import *
+from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
@@ -504,5 +504,3 @@ def test_minidump_memory64list(self):
self.assertTrue(region_info_list.GetMemoryRegionAtIndex(0, region))
self.assertEqual(region.GetRegionBase(), 0x7FFF12A84030)
self.assertTrue(region.GetRegionEnd(), 0x2FD0)
-
-
diff --git a/llvm/include/llvm/Object/Minidump.h b/llvm/include/llvm/Object/Minidump.h
index 2ebc0e07cd708..6ca9eb2afe150 100644
--- a/llvm/include/llvm/Object/Minidump.h
+++ b/llvm/include/llvm/Object/Minidump.h
@@ -106,7 +106,8 @@ class MinidumpFile : public Binary {
/// Returns the header to the memory 64 list stream. An error is returned if
/// the file does not contain this stream.
Expected<minidump::Memory64ListHeader> getMemoryList64Header() const {
- return getStream<minidump::Memory64ListHeader>(minidump::StreamType::Memory64List);
+ return getStream<minidump::Memory64ListHeader>(
+ minidump::StreamType::Memory64List);
}
Expected<ArrayRef<minidump::MemoryDescriptor_64>> getMemory64List() const;
@@ -160,8 +161,8 @@ class MinidumpFile : public Binary {
}
/// Return a slice of the given data array, with bounds checking.
- static Expected<ArrayRef<uint8_t>> getDataSlice(ArrayRef<uint8_t> Data,
- uint64_t Offset, uint64_t Size);
+ static Expected<ArrayRef<uint8_t>>
+ getDataSlice(ArrayRef<uint8_t> Data, uint64_t Offset, uint64_t Size);
/// Return the slice of the given data array as an array of objects of the
/// given type. The function checks that the input array is large enough to
diff --git a/llvm/include/llvm/ObjectYAML/MinidumpYAML.h b/llvm/include/llvm/ObjectYAML/MinidumpYAML.h
index 51fc6cc3bea89..d6aab6df1ca6f 100644
--- a/llvm/include/llvm/ObjectYAML/MinidumpYAML.h
+++ b/llvm/include/llvm/ObjectYAML/MinidumpYAML.h
@@ -111,11 +111,13 @@ struct Memory64ListStream : public Stream {
yaml::BinaryRef Content;
minidump::Memory64ListHeader Header;
- Memory64ListStream()
- : Stream(StreamKind::Memory64List, minidump::StreamType::Memory64List) {}
+ Memory64ListStream()
+ : Stream(StreamKind::Memory64List, minidump::StreamType::Memory64List) {}
- explicit Memory64ListStream(std::vector<minidump::MemoryDescriptor_64> Entries)
- : Stream(StreamKind::Memory64List, minidump::StreamType::Memory64List), Entries(Entries) {}
+ explicit Memory64ListStream(
+ std::vector<minidump::MemoryDescriptor_64> Entries)
+ : Stream(StreamKind::Memory64List, minidump::StreamType::Memory64List),
+ Entries(Entries) {}
static bool classof(const Stream *S) {
return S->Kind == StreamKind::Memory64List;
@@ -262,8 +264,10 @@ template <> struct MappingContextTraits<minidump::MemoryDescriptor, BinaryRef> {
BinaryRef &Content);
};
-template <> struct MappingContextTraits<minidump::MemoryDescriptor_64, BinaryRef> {
- static void mapping(IO &IO, minidump::MemoryDescriptor_64 &Memory, BinaryRef &Content);
+template <>
+struct MappingContextTraits<minidump::MemoryDescriptor_64, BinaryRef> {
+ static void mapping(IO &IO, minidump::MemoryDescriptor_64 &Memory,
+ BinaryRef &Content);
};
} // namespace yaml
@@ -293,7 +297,6 @@ LLVM_YAML_DECLARE_MAPPING_TRAITS(
LLVM_YAML_DECLARE_MAPPING_TRAITS(
llvm::MinidumpYAML::ThreadListStream::entry_type)
-
LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::MinidumpYAML::Stream>)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MinidumpYAML::MemoryListStream::entry_type)
LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MinidumpYAML::ModuleListStream::entry_type)
diff --git a/llvm/lib/Object/Minidump.cpp b/llvm/lib/Object/Minidump.cpp
index 422b039e618a3..92aa4f66a4b35 100644
--- a/llvm/lib/Object/Minidump.cpp
+++ b/llvm/lib/Object/Minidump.cpp
@@ -99,8 +99,9 @@ template Expected<ArrayRef<Thread>>
template Expected<ArrayRef<MemoryDescriptor>>
MinidumpFile::getListStream(StreamType) const;
-Expected<ArrayRef<uint8_t>>
-MinidumpFile::getDataSlice(ArrayRef<uint8_t> Data, uint64_t Offset, uint64_t Size) {
+Expected<ArrayRef<uint8_t>> MinidumpFile::getDataSlice(ArrayRef<uint8_t> Data,
+ uint64_t Offset,
+ uint64_t Size) {
// Check for overflow.
if (Offset + Size < Offset || Offset + Size < Size ||
Offset + Size > Data.size())
@@ -160,9 +161,11 @@ Expected<ArrayRef<MemoryDescriptor_64>> MinidumpFile::getMemory64List() const {
if (!MemoryList64)
return MemoryList64.takeError();
- std::optional<ArrayRef<uint8_t>> Stream = getRawStream(StreamType::Memory64List);
+ std::optional<ArrayRef<uint8_t>> Stream =
+ getRawStream(StreamType::Memory64List);
if (!Stream)
return createError("No such stream");
-
- return getDataSliceAs<minidump::MemoryDescriptor_64>(*Stream, sizeof(Memory64ListHeader), MemoryList64->NumberOfMemoryRanges);
+
+ return getDataSliceAs<minidump::MemoryDescriptor_64>(
+ *Stream, sizeof(Memory64ListHeader), MemoryList64->NumberOfMemoryRanges);
}
diff --git a/llvm/lib/ObjectYAML/MinidumpYAML.cpp b/llvm/lib/ObjectYAML/MinidumpYAML.cpp
index e0e883470a447..aee17c520a010 100644
--- a/llvm/lib/ObjectYAML/MinidumpYAML.cpp
+++ b/llvm/lib/ObjectYAML/MinidumpYAML.cpp
@@ -260,7 +260,8 @@ void yaml::MappingTraits<MemoryInfo>::mapping(IO &IO, MemoryInfo &Info) {
mapOptionalHex(IO, "Reserved1", Info.Reserved1, 0);
}
-void yaml::MappingTraits<MemoryDescriptor_64>::mapping(IO &IO, MemoryDescriptor_64 &Mem) {
+void yaml::MappingTraits<MemoryDescriptor_64>::mapping(
+ IO &IO, MemoryDescriptor_64 &Mem) {
mapRequiredHex(IO, "Start of memory range", Mem.StartOfMemoryRange);
mapRequiredHex(IO, "Data Size", Mem.DataSize);
}
>From f2dd958b6396e7115509b1a2065023a8de5a36a5 Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalonde at fb.com>
Date: Mon, 29 Jul 2024 14:19:45 -0700
Subject: [PATCH 6/6] Revert unchanged files.
---
.../postmortem/minidump-new/regions-linux-map.yaml | 12 ++++++------
.../minidump-new/relative_module_name.yaml | 8 ++++----
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/lldb/test/API/functionalities/postmortem/minidump-new/regions-linux-map.yaml b/lldb/test/API/functionalities/postmortem/minidump-new/regions-linux-map.yaml
index 4b6a844a38dd4..3c0961eba077d 100644
--- a/lldb/test/API/functionalities/postmortem/minidump-new/regions-linux-map.yaml
+++ b/lldb/test/API/functionalities/postmortem/minidump-new/regions-linux-map.yaml
@@ -1,10 +1,10 @@
--- !minidump
-Streams:
+Streams:
- Type: SystemInfo
Processor Arch: ARM64
Platform ID: Linux
CSD Version: '15E216'
- CPU:
+ CPU:
CPUID: 0x00000000
- Type: MiscInfo
Content: 00000000010000007B000000000000000000000000000000
@@ -12,12 +12,12 @@ Streams:
Text: |
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
+ 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
+ 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
+ 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
@@ -28,6 +28,6 @@ Streams:
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
+ 4016b000-40176000 rw-p 00000000 00:00 0
...
diff --git a/lldb/test/API/functionalities/postmortem/minidump-new/relative_module_name.yaml b/lldb/test/API/functionalities/postmortem/minidump-new/relative_module_name.yaml
index ecab417f9cd41..23f2b49028039 100644
--- a/lldb/test/API/functionalities/postmortem/minidump-new/relative_module_name.yaml
+++ b/lldb/test/API/functionalities/postmortem/minidump-new/relative_module_name.yaml
@@ -1,15 +1,15 @@
--- !minidump
-Streams:
+Streams:
- Type: SystemInfo
Processor Arch: AMD64
Platform ID: Linux
CSD Version: '15E216'
- CPU:
- Vendor ID: GenuineIntelâ€
+ CPU:
+ Vendor ID: GenuineIntel
Version Info: 0x00000000
Feature Info: 0x00000000
- Type: ModuleList
- Modules:
+ Modules:
- Base of Image: 0x0000000000001000
Size of Image: 0x00001000
Module Name: 'file-with-a-name-unlikely-to-exist-in-the-current-directory.so'
More information about the lldb-commits
mailing list