[Lldb-commits] [lldb] [LLDB][SBSaveCore] Sbsavecore subregions bug (PR #138206)
Jacob Lalonde via lldb-commits
lldb-commits at lists.llvm.org
Fri May 2 12:51:03 PDT 2025
https://github.com/Jlalond updated https://github.com/llvm/llvm-project/pull/138206
>From 91ce0997c03f87ec617ec2a113e7e88f1a88de11 Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalonde at fb.com>
Date: Thu, 1 May 2025 14:53:08 -0700
Subject: [PATCH 1/7] Change custom regions to be intersections, add test cases
for sub regions and super regions, plus changes of permissions and invalid
pages.
---
lldb/include/lldb/Utility/RangeMap.h | 19 +++
lldb/source/Target/Process.cpp | 30 +++-
.../TestProcessSaveCoreMinidumpYaml.py | 142 ++++++++++++++++++
.../minidump_mem64.yaml | 35 +++++
4 files changed, 223 insertions(+), 3 deletions(-)
create mode 100644 lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidumpYaml.py
create mode 100644 lldb/test/API/functionalities/process_save_core_minidump/minidump_mem64.yaml
diff --git a/lldb/include/lldb/Utility/RangeMap.h b/lldb/include/lldb/Utility/RangeMap.h
index 8af690e813c4a..f19c28268d55c 100644
--- a/lldb/include/lldb/Utility/RangeMap.h
+++ b/lldb/include/lldb/Utility/RangeMap.h
@@ -380,6 +380,25 @@ template <typename B, typename S, unsigned N = 0> class RangeVector {
return nullptr;
}
+const Entry* FindEntryThatIntersects(const Entry &range) const {
+ #ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert(IsSorted());
+ #endif
+ if (!m_entries.empty()) {
+ typename Collection::const_iterator begin = m_entries.begin();
+ typename Collection::const_iterator end = m_entries.end();
+ typename Collection::const_iterator pos =
+ std::lower_bound(begin, end, range, BaseLessThan);
+
+ while (pos != begin && pos[-1].DoesIntersect(range))
+ --pos;
+
+ if (pos != end && pos->DoesIntersect(range))
+ return &(*pos);
+ }
+ return nullptr;
+ }
+
using const_iterator = typename Collection::const_iterator;
const_iterator begin() const { return m_entries.begin(); }
const_iterator end() const { return m_entries.end(); }
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 73557eb767c72..ee297e1ca3d4a 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -6689,6 +6689,23 @@ static void GetCoreFileSaveRangesStackOnly(Process &process,
}
}
+// TODO: We should refactor CoreFileMemoryRanges to use the lldb range type, and then
+// add an intersect method on it, or MemoryRegionInfo.
+static MemoryRegionInfo Intersect(const MemoryRegionInfo &lhs, const Range<lldb::addr_t, lldb::addr_t> &rhs) {
+ const lldb::addr_t lhs_base = lhs.GetRange().GetRangeBase();
+ const lldb::addr_t rhs_base = rhs.GetRangeBase();
+ const lldb::addr_t lhs_end = lhs.GetRange().GetRangeEnd();
+ const lldb::addr_t rhs_end = rhs.GetRangeEnd();
+
+ MemoryRegionInfo region_info;
+ region_info.SetLLDBPermissions(lhs.GetLLDBPermissions());
+ auto &range = region_info.GetRange();
+ range.SetRangeBase(std::max(lhs_base, rhs_base));
+ range.SetRangeEnd(std::min(lhs_end, rhs_end));
+
+ return region_info;
+}
+
static void GetUserSpecifiedCoreFileSaveRanges(Process &process,
const MemoryRegionInfos ®ions,
const SaveCoreOptions &options,
@@ -6698,9 +6715,16 @@ static void GetUserSpecifiedCoreFileSaveRanges(Process &process,
return;
for (const auto &range : regions) {
- auto entry = option_ranges.FindEntryThatContains(range.GetRange());
- if (entry)
- AddRegion(range, true, ranges);
+ auto *entry = option_ranges.FindEntryThatIntersects(range.GetRange());
+ if (entry) {
+ if (entry->GetRangeBase() != range.GetRange().GetRangeBase()
+ || entry->GetRangeEnd() != range.GetRange().GetRangeEnd()) {
+ AddRegion(Intersect(range, *entry), true, ranges);
+ } else {
+ // If they match, add the range directly.
+ AddRegion(range, true, ranges);
+ }
+ }
}
}
diff --git a/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidumpYaml.py b/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidumpYaml.py
new file mode 100644
index 0000000000000..b8f9d697c8864
--- /dev/null
+++ b/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidumpYaml.py
@@ -0,0 +1,142 @@
+"""
+Test saving a mini dump, from yamilized examples.
+"""
+
+import os
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class ProcessSaveCoreMinidumpTestCaseYaml(TestBase):
+ def process_from_yaml(self, yaml_file):
+ minidump_path = self.getBuildArtifact(os.path.basename(yaml_file) + ".dmp")
+ self.yaml2obj(yaml_file, minidump_path)
+ self.target = self.dbg.CreateTarget(None)
+ self.process = self.target.LoadCore(minidump_path)
+ return self.process
+
+ def test_saving_sub_memory_range(self):
+ """
+ Validate we can save a Minidump for a subsection of a memory range.
+ I.E.
+ If our memory range is 0x1000-0x2000 nd the user specifies 0x1200-0x1800
+ we should still capture 0x1200 to 0x1800
+ """
+ yaml = "minidump_mem64.yaml"
+ proc = self.process_from_yaml(yaml)
+ new_minidump_path = self.getBuildArtifact(__name__ + ".dmp")
+ options = lldb.SBSaveCoreOptions()
+ options.SetOutputFile(lldb.SBFileSpec(new_minidump_path))
+ options.SetPluginName("minidump")
+ options.SetStyle(lldb.eSaveCoreCustomOnly)
+
+ size = 8
+ begin = 0x7FFF12A84030
+ end = begin + size
+ custom_range = lldb.SBMemoryRegionInfo("", begin, end, 3, True, False)
+ options.AddMemoryRegionToSave(custom_range)
+
+ error = proc.SaveCore(options)
+ self.assertTrue(error.Success(), error.GetCString())
+ core_target = self.dbg.CreateTarget(None)
+ core_process = core_target.LoadCore(new_minidump_path)
+
+ error = lldb.SBError()
+ core_process.ReadMemory(begin, size, error)
+ self.assertTrue(error.Success(), error.GetCString())
+
+ # Try to read 1 byte past the end
+ core_process.ReadMemory(end + 1, 1, error)
+ self.assertTrue(error.Fail(), error.GetCString())
+
+ def test_saving_super_memory_range(self):
+ """
+ Validate we can save a Minidump for a subsection of a memory range.
+ I.E.
+ If our memory range is 0x1000-0x2000 nd the user specifies 0x0800-0x2800
+ we should still capture 0x1000-0x2000
+ """
+ yaml = "minidump_mem64.yaml"
+ proc = self.process_from_yaml(yaml)
+ new_minidump_path = self.getBuildArtifact(__name__ + ".dmp")
+ options = lldb.SBSaveCoreOptions()
+ options.SetOutputFile(lldb.SBFileSpec(new_minidump_path))
+ options.SetPluginName("minidump")
+ options.SetStyle(lldb.eSaveCoreCustomOnly)
+
+ size = 0x2FD0
+ begin = 0x7FFF12A84030
+ end = begin + size
+ custom_range = lldb.SBMemoryRegionInfo("", begin - 16, end + 16, 3, True, False)
+ options.AddMemoryRegionToSave(custom_range)
+
+ error = proc.SaveCore(options)
+ self.assertTrue(error.Success(), error.GetCString())
+ core_target = self.dbg.CreateTarget(None)
+ core_process = core_target.LoadCore(new_minidump_path)
+
+ error = lldb.SBError()
+ core_process.ReadMemory(begin, size, error)
+ self.assertTrue(error.Success(), error.GetCString())
+
+
+ def test_region_that_goes_out_of_bounds(self):
+ """
+ Validate we can save a Minidump for a custom region
+ that includes an end that enters an invalid (---) page.
+ """
+ yaml = "minidump_mem64.yaml"
+ proc = self.process_from_yaml(yaml)
+ new_minidump_path = self.getBuildArtifact(__name__ + ".dmp")
+ options = lldb.SBSaveCoreOptions()
+ options.SetOutputFile(lldb.SBFileSpec(new_minidump_path))
+ options.SetPluginName("minidump")
+ options.SetStyle(lldb.eSaveCoreCustomOnly)
+
+ size = 1024
+ begin = 0x00007fff12a8ffff
+ end = begin + size
+ custom_range = lldb.SBMemoryRegionInfo("", begin, end, 3, True, False)
+ options.AddMemoryRegionToSave(custom_range)
+
+ error = proc.SaveCore(options)
+ self.assertTrue(error.Success(), error.GetCString())
+ core_target = self.dbg.CreateTarget(None)
+ core_process = core_target.LoadCore(new_minidump_path)
+
+ error = lldb.SBError()
+ core_process.ReadMemory(begin, 0x00000020, error)
+ self.assertTrue(error.Success(), error.GetCString())
+
+ # Whole region should be unavailable
+ core_process.ReadMemory(end, 1, error)
+ self.assertTrue(error.Fail(), error.GetCString())
+
+ def test_region_that_starts_out_of_bounds(self):
+ """
+ Validate we can save a Minidump for a custom region
+ that includes a start in a (---) page but ends in a valid page.
+ """
+ yaml = "minidump_mem64.yaml"
+ proc = self.process_from_yaml(yaml)
+ new_minidump_path = self.getBuildArtifact(__name__ + ".dmp")
+ options = lldb.SBSaveCoreOptions()
+ options.SetOutputFile(lldb.SBFileSpec(new_minidump_path))
+ options.SetPluginName("minidump")
+ options.SetStyle(lldb.eSaveCoreCustomOnly)
+
+ size = 0x00000020
+ begin = 0x00007fff12a8ffff
+ end = begin + size
+ custom_range = lldb.SBMemoryRegionInfo("", begin - 16, end, 3, True, False)
+ options.AddMemoryRegionToSave(custom_range)
+
+ error = proc.SaveCore(options)
+ self.assertTrue(error.Success(), error.GetCString())
+ core_target = self.dbg.CreateTarget(None)
+ core_process = core_target.LoadCore(new_minidump_path)
+
+ error = lldb.SBError()
+ core_process.ReadMemory(begin, 0x00000020, error)
+ self.assertTrue(error.Success(), error.GetCString())
diff --git a/lldb/test/API/functionalities/process_save_core_minidump/minidump_mem64.yaml b/lldb/test/API/functionalities/process_save_core_minidump/minidump_mem64.yaml
new file mode 100644
index 0000000000000..24fdcc8aed74a
--- /dev/null
+++ b/lldb/test/API/functionalities/process_save_core_minidump/minidump_mem64.yaml
@@ -0,0 +1,35 @@
+--- !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: ThreadList
+ Threads:
+ - Thread Id: 0x2896BB
+ Context: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000700100000000000FFFFFFFF0000FFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B040A812FF7F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000050D0A75BBA7F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+ Stack:
+ Start of Memory Range: 0x0
+ Content: ''
+ - Type: Memory64List
+ Memory Ranges:
+ - Start of Memory Range: 0x7FFF12A84030
+ Data Size: 0x2FD0
+ Content : ''
+ - Start of Memory Range: 0x00007fff12a87000
+ Data Size: 0x00000018
+ Content : ''
+ - Start of Memory Range: 0x00007fff12a87018
+ Data Size: 0x00000400
+ Content : ''
+ - Start of Memory Range: 0x00007fff12a8ffff
+ Data Size: 0x00000020
+ Content : ''
+...
>From 024254ef2ec422301fbc575a458398fbffba65f0 Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalonde at fb.com>
Date: Thu, 1 May 2025 14:53:29 -0700
Subject: [PATCH 2/7] GCF
---
lldb/include/lldb/Utility/RangeMap.h | 34 ++++++++++++++--------------
lldb/source/Target/Process.cpp | 12 ++++++----
2 files changed, 24 insertions(+), 22 deletions(-)
diff --git a/lldb/include/lldb/Utility/RangeMap.h b/lldb/include/lldb/Utility/RangeMap.h
index f19c28268d55c..2f7711c1eb11e 100644
--- a/lldb/include/lldb/Utility/RangeMap.h
+++ b/lldb/include/lldb/Utility/RangeMap.h
@@ -380,24 +380,24 @@ template <typename B, typename S, unsigned N = 0> class RangeVector {
return nullptr;
}
-const Entry* FindEntryThatIntersects(const Entry &range) const {
- #ifdef ASSERT_RANGEMAP_ARE_SORTED
- assert(IsSorted());
- #endif
- if (!m_entries.empty()) {
- typename Collection::const_iterator begin = m_entries.begin();
- typename Collection::const_iterator end = m_entries.end();
- typename Collection::const_iterator pos =
- std::lower_bound(begin, end, range, BaseLessThan);
-
- while (pos != begin && pos[-1].DoesIntersect(range))
- --pos;
-
- if (pos != end && pos->DoesIntersect(range))
- return &(*pos);
- }
- return nullptr;
+ const Entry *FindEntryThatIntersects(const Entry &range) const {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert(IsSorted());
+#endif
+ if (!m_entries.empty()) {
+ typename Collection::const_iterator begin = m_entries.begin();
+ typename Collection::const_iterator end = m_entries.end();
+ typename Collection::const_iterator pos =
+ std::lower_bound(begin, end, range, BaseLessThan);
+
+ while (pos != begin && pos[-1].DoesIntersect(range))
+ --pos;
+
+ if (pos != end && pos->DoesIntersect(range))
+ return &(*pos);
}
+ return nullptr;
+ }
using const_iterator = typename Collection::const_iterator;
const_iterator begin() const { return m_entries.begin(); }
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index ee297e1ca3d4a..7d6cded48b21a 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -6689,9 +6689,11 @@ static void GetCoreFileSaveRangesStackOnly(Process &process,
}
}
-// TODO: We should refactor CoreFileMemoryRanges to use the lldb range type, and then
-// add an intersect method on it, or MemoryRegionInfo.
-static MemoryRegionInfo Intersect(const MemoryRegionInfo &lhs, const Range<lldb::addr_t, lldb::addr_t> &rhs) {
+// TODO: We should refactor CoreFileMemoryRanges to use the lldb range type, and
+// then add an intersect method on it, or MemoryRegionInfo.
+static MemoryRegionInfo
+Intersect(const MemoryRegionInfo &lhs,
+ const Range<lldb::addr_t, lldb::addr_t> &rhs) {
const lldb::addr_t lhs_base = lhs.GetRange().GetRangeBase();
const lldb::addr_t rhs_base = rhs.GetRangeBase();
const lldb::addr_t lhs_end = lhs.GetRange().GetRangeEnd();
@@ -6717,8 +6719,8 @@ static void GetUserSpecifiedCoreFileSaveRanges(Process &process,
for (const auto &range : regions) {
auto *entry = option_ranges.FindEntryThatIntersects(range.GetRange());
if (entry) {
- if (entry->GetRangeBase() != range.GetRange().GetRangeBase()
- || entry->GetRangeEnd() != range.GetRange().GetRangeEnd()) {
+ if (entry->GetRangeBase() != range.GetRange().GetRangeBase() ||
+ entry->GetRangeEnd() != range.GetRange().GetRangeEnd()) {
AddRegion(Intersect(range, *entry), true, ranges);
} else {
// If they match, add the range directly.
>From 200533a8f1f21f906145d505f275fec2aaa42027 Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalonde at fb.com>
Date: Thu, 1 May 2025 15:02:05 -0700
Subject: [PATCH 3/7] Py formatting
---
.../TestProcessSaveCoreMinidumpYaml.py | 262 +++++++++---------
1 file changed, 131 insertions(+), 131 deletions(-)
diff --git a/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidumpYaml.py b/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidumpYaml.py
index b8f9d697c8864..f6c1064282727 100644
--- a/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidumpYaml.py
+++ b/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidumpYaml.py
@@ -8,135 +8,135 @@
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
+
class ProcessSaveCoreMinidumpTestCaseYaml(TestBase):
- def process_from_yaml(self, yaml_file):
- minidump_path = self.getBuildArtifact(os.path.basename(yaml_file) + ".dmp")
- self.yaml2obj(yaml_file, minidump_path)
- self.target = self.dbg.CreateTarget(None)
- self.process = self.target.LoadCore(minidump_path)
- return self.process
-
- def test_saving_sub_memory_range(self):
- """
- Validate we can save a Minidump for a subsection of a memory range.
- I.E.
- If our memory range is 0x1000-0x2000 nd the user specifies 0x1200-0x1800
- we should still capture 0x1200 to 0x1800
- """
- yaml = "minidump_mem64.yaml"
- proc = self.process_from_yaml(yaml)
- new_minidump_path = self.getBuildArtifact(__name__ + ".dmp")
- options = lldb.SBSaveCoreOptions()
- options.SetOutputFile(lldb.SBFileSpec(new_minidump_path))
- options.SetPluginName("minidump")
- options.SetStyle(lldb.eSaveCoreCustomOnly)
-
- size = 8
- begin = 0x7FFF12A84030
- end = begin + size
- custom_range = lldb.SBMemoryRegionInfo("", begin, end, 3, True, False)
- options.AddMemoryRegionToSave(custom_range)
-
- error = proc.SaveCore(options)
- self.assertTrue(error.Success(), error.GetCString())
- core_target = self.dbg.CreateTarget(None)
- core_process = core_target.LoadCore(new_minidump_path)
-
- error = lldb.SBError()
- core_process.ReadMemory(begin, size, error)
- self.assertTrue(error.Success(), error.GetCString())
-
- # Try to read 1 byte past the end
- core_process.ReadMemory(end + 1, 1, error)
- self.assertTrue(error.Fail(), error.GetCString())
-
- def test_saving_super_memory_range(self):
- """
- Validate we can save a Minidump for a subsection of a memory range.
- I.E.
- If our memory range is 0x1000-0x2000 nd the user specifies 0x0800-0x2800
- we should still capture 0x1000-0x2000
- """
- yaml = "minidump_mem64.yaml"
- proc = self.process_from_yaml(yaml)
- new_minidump_path = self.getBuildArtifact(__name__ + ".dmp")
- options = lldb.SBSaveCoreOptions()
- options.SetOutputFile(lldb.SBFileSpec(new_minidump_path))
- options.SetPluginName("minidump")
- options.SetStyle(lldb.eSaveCoreCustomOnly)
-
- size = 0x2FD0
- begin = 0x7FFF12A84030
- end = begin + size
- custom_range = lldb.SBMemoryRegionInfo("", begin - 16, end + 16, 3, True, False)
- options.AddMemoryRegionToSave(custom_range)
-
- error = proc.SaveCore(options)
- self.assertTrue(error.Success(), error.GetCString())
- core_target = self.dbg.CreateTarget(None)
- core_process = core_target.LoadCore(new_minidump_path)
-
- error = lldb.SBError()
- core_process.ReadMemory(begin, size, error)
- self.assertTrue(error.Success(), error.GetCString())
-
-
- def test_region_that_goes_out_of_bounds(self):
- """
- Validate we can save a Minidump for a custom region
- that includes an end that enters an invalid (---) page.
- """
- yaml = "minidump_mem64.yaml"
- proc = self.process_from_yaml(yaml)
- new_minidump_path = self.getBuildArtifact(__name__ + ".dmp")
- options = lldb.SBSaveCoreOptions()
- options.SetOutputFile(lldb.SBFileSpec(new_minidump_path))
- options.SetPluginName("minidump")
- options.SetStyle(lldb.eSaveCoreCustomOnly)
-
- size = 1024
- begin = 0x00007fff12a8ffff
- end = begin + size
- custom_range = lldb.SBMemoryRegionInfo("", begin, end, 3, True, False)
- options.AddMemoryRegionToSave(custom_range)
-
- error = proc.SaveCore(options)
- self.assertTrue(error.Success(), error.GetCString())
- core_target = self.dbg.CreateTarget(None)
- core_process = core_target.LoadCore(new_minidump_path)
-
- error = lldb.SBError()
- core_process.ReadMemory(begin, 0x00000020, error)
- self.assertTrue(error.Success(), error.GetCString())
-
- # Whole region should be unavailable
- core_process.ReadMemory(end, 1, error)
- self.assertTrue(error.Fail(), error.GetCString())
-
- def test_region_that_starts_out_of_bounds(self):
- """
- Validate we can save a Minidump for a custom region
- that includes a start in a (---) page but ends in a valid page.
- """
- yaml = "minidump_mem64.yaml"
- proc = self.process_from_yaml(yaml)
- new_minidump_path = self.getBuildArtifact(__name__ + ".dmp")
- options = lldb.SBSaveCoreOptions()
- options.SetOutputFile(lldb.SBFileSpec(new_minidump_path))
- options.SetPluginName("minidump")
- options.SetStyle(lldb.eSaveCoreCustomOnly)
-
- size = 0x00000020
- begin = 0x00007fff12a8ffff
- end = begin + size
- custom_range = lldb.SBMemoryRegionInfo("", begin - 16, end, 3, True, False)
- options.AddMemoryRegionToSave(custom_range)
-
- error = proc.SaveCore(options)
- self.assertTrue(error.Success(), error.GetCString())
- core_target = self.dbg.CreateTarget(None)
- core_process = core_target.LoadCore(new_minidump_path)
-
- error = lldb.SBError()
- core_process.ReadMemory(begin, 0x00000020, error)
- self.assertTrue(error.Success(), error.GetCString())
+ def process_from_yaml(self, yaml_file):
+ minidump_path = self.getBuildArtifact(os.path.basename(yaml_file) + ".dmp")
+ self.yaml2obj(yaml_file, minidump_path)
+ self.target = self.dbg.CreateTarget(None)
+ self.process = self.target.LoadCore(minidump_path)
+ return self.process
+
+ def test_saving_sub_memory_range(self):
+ """
+ Validate we can save a Minidump for a subsection of a memory range.
+ I.E.
+ If our memory range is 0x1000-0x2000 nd the user specifies 0x1200-0x1800
+ we should still capture 0x1200 to 0x1800
+ """
+ yaml = "minidump_mem64.yaml"
+ proc = self.process_from_yaml(yaml)
+ new_minidump_path = self.getBuildArtifact(__name__ + ".dmp")
+ options = lldb.SBSaveCoreOptions()
+ options.SetOutputFile(lldb.SBFileSpec(new_minidump_path))
+ options.SetPluginName("minidump")
+ options.SetStyle(lldb.eSaveCoreCustomOnly)
+
+ size = 8
+ begin = 0x7FFF12A84030
+ end = begin + size
+ custom_range = lldb.SBMemoryRegionInfo("", begin, end, 3, True, False)
+ options.AddMemoryRegionToSave(custom_range)
+
+ error = proc.SaveCore(options)
+ self.assertTrue(error.Success(), error.GetCString())
+ core_target = self.dbg.CreateTarget(None)
+ core_process = core_target.LoadCore(new_minidump_path)
+
+ error = lldb.SBError()
+ core_process.ReadMemory(begin, size, error)
+ self.assertTrue(error.Success(), error.GetCString())
+
+ # Try to read 1 byte past the end
+ core_process.ReadMemory(end + 1, 1, error)
+ self.assertTrue(error.Fail(), error.GetCString())
+
+ def test_saving_super_memory_range(self):
+ """
+ Validate we can save a Minidump for a subsection of a memory range.
+ I.E.
+ If our memory range is 0x1000-0x2000 nd the user specifies 0x0800-0x2800
+ we should still capture 0x1000-0x2000
+ """
+ yaml = "minidump_mem64.yaml"
+ proc = self.process_from_yaml(yaml)
+ new_minidump_path = self.getBuildArtifact(__name__ + ".dmp")
+ options = lldb.SBSaveCoreOptions()
+ options.SetOutputFile(lldb.SBFileSpec(new_minidump_path))
+ options.SetPluginName("minidump")
+ options.SetStyle(lldb.eSaveCoreCustomOnly)
+
+ size = 0x2FD0
+ begin = 0x7FFF12A84030
+ end = begin + size
+ custom_range = lldb.SBMemoryRegionInfo("", begin - 16, end + 16, 3, True, False)
+ options.AddMemoryRegionToSave(custom_range)
+
+ error = proc.SaveCore(options)
+ self.assertTrue(error.Success(), error.GetCString())
+ core_target = self.dbg.CreateTarget(None)
+ core_process = core_target.LoadCore(new_minidump_path)
+
+ error = lldb.SBError()
+ core_process.ReadMemory(begin, size, error)
+ self.assertTrue(error.Success(), error.GetCString())
+
+ def test_region_that_goes_out_of_bounds(self):
+ """
+ Validate we can save a Minidump for a custom region
+ that includes an end that enters an invalid (---) page.
+ """
+ yaml = "minidump_mem64.yaml"
+ proc = self.process_from_yaml(yaml)
+ new_minidump_path = self.getBuildArtifact(__name__ + ".dmp")
+ options = lldb.SBSaveCoreOptions()
+ options.SetOutputFile(lldb.SBFileSpec(new_minidump_path))
+ options.SetPluginName("minidump")
+ options.SetStyle(lldb.eSaveCoreCustomOnly)
+
+ size = 1024
+ begin = 0x00007FFF12A8FFFF
+ end = begin + size
+ custom_range = lldb.SBMemoryRegionInfo("", begin, end, 3, True, False)
+ options.AddMemoryRegionToSave(custom_range)
+
+ error = proc.SaveCore(options)
+ self.assertTrue(error.Success(), error.GetCString())
+ core_target = self.dbg.CreateTarget(None)
+ core_process = core_target.LoadCore(new_minidump_path)
+
+ error = lldb.SBError()
+ core_process.ReadMemory(begin, 0x00000020, error)
+ self.assertTrue(error.Success(), error.GetCString())
+
+ # Whole region should be unavailable
+ core_process.ReadMemory(end, 1, error)
+ self.assertTrue(error.Fail(), error.GetCString())
+
+ def test_region_that_starts_out_of_bounds(self):
+ """
+ Validate we can save a Minidump for a custom region
+ that includes a start in a (---) page but ends in a valid page.
+ """
+ yaml = "minidump_mem64.yaml"
+ proc = self.process_from_yaml(yaml)
+ new_minidump_path = self.getBuildArtifact(__name__ + ".dmp")
+ options = lldb.SBSaveCoreOptions()
+ options.SetOutputFile(lldb.SBFileSpec(new_minidump_path))
+ options.SetPluginName("minidump")
+ options.SetStyle(lldb.eSaveCoreCustomOnly)
+
+ size = 0x00000020
+ begin = 0x00007FFF12A8FFFF
+ end = begin + size
+ custom_range = lldb.SBMemoryRegionInfo("", begin - 16, end, 3, True, False)
+ options.AddMemoryRegionToSave(custom_range)
+
+ error = proc.SaveCore(options)
+ self.assertTrue(error.Success(), error.GetCString())
+ core_target = self.dbg.CreateTarget(None)
+ core_process = core_target.LoadCore(new_minidump_path)
+
+ error = lldb.SBError()
+ core_process.ReadMemory(begin, 0x00000020, error)
+ self.assertTrue(error.Success(), error.GetCString())
>From 811f64c8b6643c8f465b21c9de7acb65e049b655 Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalonde at fb.com>
Date: Thu, 1 May 2025 15:52:43 -0700
Subject: [PATCH 4/7] Clean up code duplication and use the existing functions
on Range
---
lldb/source/Target/Process.cpp | 16 ++++------------
.../TestProcessSaveCoreMinidumpYaml.py | 14 +++++++-------
.../minidump_mem64.yaml | 16 ++++++++--------
3 files changed, 19 insertions(+), 27 deletions(-)
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 7d6cded48b21a..62493f978f2d0 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -6691,19 +6691,12 @@ static void GetCoreFileSaveRangesStackOnly(Process &process,
// TODO: We should refactor CoreFileMemoryRanges to use the lldb range type, and
// then add an intersect method on it, or MemoryRegionInfo.
-static MemoryRegionInfo
-Intersect(const MemoryRegionInfo &lhs,
- const Range<lldb::addr_t, lldb::addr_t> &rhs) {
- const lldb::addr_t lhs_base = lhs.GetRange().GetRangeBase();
- const lldb::addr_t rhs_base = rhs.GetRangeBase();
- const lldb::addr_t lhs_end = lhs.GetRange().GetRangeEnd();
- const lldb::addr_t rhs_end = rhs.GetRangeEnd();
+static MemoryRegionInfo Intersect(const MemoryRegionInfo &lhs,
+ const MemoryRegionInfo::RangeType &rhs) {
MemoryRegionInfo region_info;
region_info.SetLLDBPermissions(lhs.GetLLDBPermissions());
- auto &range = region_info.GetRange();
- range.SetRangeBase(std::max(lhs_base, rhs_base));
- range.SetRangeEnd(std::min(lhs_end, rhs_end));
+ region_info.GetRange() = lhs.GetRange().Intersect(rhs);
return region_info;
}
@@ -6719,8 +6712,7 @@ static void GetUserSpecifiedCoreFileSaveRanges(Process &process,
for (const auto &range : regions) {
auto *entry = option_ranges.FindEntryThatIntersects(range.GetRange());
if (entry) {
- if (entry->GetRangeBase() != range.GetRange().GetRangeBase() ||
- entry->GetRangeEnd() != range.GetRange().GetRangeEnd()) {
+ if (*entry != range.GetRange()) {
AddRegion(Intersect(range, *entry), true, ranges);
} else {
// If they match, add the range directly.
diff --git a/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidumpYaml.py b/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidumpYaml.py
index f6c1064282727..434e9a620cfaa 100644
--- a/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidumpYaml.py
+++ b/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidumpYaml.py
@@ -33,7 +33,7 @@ def test_saving_sub_memory_range(self):
options.SetStyle(lldb.eSaveCoreCustomOnly)
size = 8
- begin = 0x7FFF12A84030
+ begin = 0x2000
end = begin + size
custom_range = lldb.SBMemoryRegionInfo("", begin, end, 3, True, False)
options.AddMemoryRegionToSave(custom_range)
@@ -66,8 +66,8 @@ def test_saving_super_memory_range(self):
options.SetPluginName("minidump")
options.SetStyle(lldb.eSaveCoreCustomOnly)
- size = 0x2FD0
- begin = 0x7FFF12A84030
+ size = 0x100
+ begin = 0x1000
end = begin + size
custom_range = lldb.SBMemoryRegionInfo("", begin - 16, end + 16, 3, True, False)
options.AddMemoryRegionToSave(custom_range)
@@ -94,8 +94,8 @@ def test_region_that_goes_out_of_bounds(self):
options.SetPluginName("minidump")
options.SetStyle(lldb.eSaveCoreCustomOnly)
- size = 1024
- begin = 0x00007FFF12A8FFFF
+ size = 0x120
+ begin = 0x1000
end = begin + size
custom_range = lldb.SBMemoryRegionInfo("", begin, end, 3, True, False)
options.AddMemoryRegionToSave(custom_range)
@@ -126,8 +126,8 @@ def test_region_that_starts_out_of_bounds(self):
options.SetPluginName("minidump")
options.SetStyle(lldb.eSaveCoreCustomOnly)
- size = 0x00000020
- begin = 0x00007FFF12A8FFFF
+ size = 0x20
+ begin = 0x2000
end = begin + size
custom_range = lldb.SBMemoryRegionInfo("", begin - 16, end, 3, True, False)
options.AddMemoryRegionToSave(custom_range)
diff --git a/lldb/test/API/functionalities/process_save_core_minidump/minidump_mem64.yaml b/lldb/test/API/functionalities/process_save_core_minidump/minidump_mem64.yaml
index 24fdcc8aed74a..6c9c510b87a05 100644
--- a/lldb/test/API/functionalities/process_save_core_minidump/minidump_mem64.yaml
+++ b/lldb/test/API/functionalities/process_save_core_minidump/minidump_mem64.yaml
@@ -20,16 +20,16 @@ Streams:
Content: ''
- Type: Memory64List
Memory Ranges:
- - Start of Memory Range: 0x7FFF12A84030
- Data Size: 0x2FD0
+ - Start of Memory Range: 0x1000
+ Data Size: 0x100
Content : ''
- - Start of Memory Range: 0x00007fff12a87000
- Data Size: 0x00000018
+ - Start of Memory Range: 0x2000
+ Data Size: 0x20
Content : ''
- - Start of Memory Range: 0x00007fff12a87018
- Data Size: 0x00000400
+ - Start of Memory Range: 0x3000
+ Data Size: 0x4000
Content : ''
- - Start of Memory Range: 0x00007fff12a8ffff
- Data Size: 0x00000020
+ - Start of Memory Range: 0x5000
+ Data Size: 0x2000
Content : ''
...
>From afb0a6a6eebc799e6084dee799609c10783d9510 Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalonde at fb.com>
Date: Fri, 2 May 2025 08:36:20 -0700
Subject: [PATCH 5/7] Move test validation into helper method, do validation of
expected and expected invalid ranges
---
.../TestProcessSaveCoreMinidumpYaml.py | 71 ++++++++++++-------
.../minidump_mem64.yaml | 2 +-
2 files changed, 48 insertions(+), 25 deletions(-)
diff --git a/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidumpYaml.py b/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidumpYaml.py
index 434e9a620cfaa..f629e3536b186 100644
--- a/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidumpYaml.py
+++ b/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidumpYaml.py
@@ -7,6 +7,15 @@
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
+from dataclass import dataclass
+
+class AddressRange:
+ begin: int
+ end: int
+
+ def __init__(self, begin, end):
+ self.begin = begin
+ self.end = end
class ProcessSaveCoreMinidumpTestCaseYaml(TestBase):
@@ -17,12 +26,34 @@ def process_from_yaml(self, yaml_file):
self.process = self.target.LoadCore(minidump_path)
return self.process
+ def validate_regions_saved_correctly(self, core_process, expected_region, expected_invalid_region=None):
+ """ Validate that the expected_region is saved in the core_proc, and that the expected invalid region is not saved, if not not none. """
+
+ # Validate we can read the entire expected_region
+ error = lldb.SBError()
+ core_process.ReadMemory(expected_region.begin, expected_region.end - expected_region.begin, error)
+ self.assertTrue(error.Success(), error.GetCString())
+
+ # Validate we can't read before and after the expected_region
+ core_process.ReadMemory(expected_region.begin - 1, 1, error)
+ self.assertTrue(error.Fail(), error.GetCString())
+
+ core_process.ReadMemory(expected_region.end + 1, 1, error)
+ self.assertTrue(error.Fail(), error.GetCString())
+
+ if expected_invalid_region is None:
+ return
+
+ # Validate we can't read the original_region
+ core_process.ReadMemory(expected_invalid_region.begin, expected_invalid_region.end - expected_invalid_region.end, error)
+ self.assertTrue(error.Success(), error.GetCString())
+
def test_saving_sub_memory_range(self):
"""
Validate we can save a Minidump for a subsection of a memory range.
I.E.
- If our memory range is 0x1000-0x2000 nd the user specifies 0x1200-0x1800
- we should still capture 0x1200 to 0x1800
+ If our memory range is 0x2000-0x2020 and the user specifies 0x2000-0x2008
+ we should still capture 0x2000-0x2008
"""
yaml = "minidump_mem64.yaml"
proc = self.process_from_yaml(yaml)
@@ -43,20 +74,16 @@ def test_saving_sub_memory_range(self):
core_target = self.dbg.CreateTarget(None)
core_process = core_target.LoadCore(new_minidump_path)
- error = lldb.SBError()
- core_process.ReadMemory(begin, size, error)
- self.assertTrue(error.Success(), error.GetCString())
-
- # Try to read 1 byte past the end
- core_process.ReadMemory(end + 1, 1, error)
- self.assertTrue(error.Fail(), error.GetCString())
+ expected_address_range = AddressRange(begin, end)
+ expected_invalid_range = AddressRange(begin, 0x2020)
+ self.validate_regions_saved_correctly(core_process, expected_address_range, expected_invalid_range)
def test_saving_super_memory_range(self):
"""
Validate we can save a Minidump for a subsection of a memory range.
I.E.
- If our memory range is 0x1000-0x2000 nd the user specifies 0x0800-0x2800
- we should still capture 0x1000-0x2000
+ If our memory range is 0x1000-0x1100 and the user specifies 0x900-x1200
+ we should still capture 0x1000-0x1100
"""
yaml = "minidump_mem64.yaml"
proc = self.process_from_yaml(yaml)
@@ -77,9 +104,9 @@ def test_saving_super_memory_range(self):
core_target = self.dbg.CreateTarget(None)
core_process = core_target.LoadCore(new_minidump_path)
- error = lldb.SBError()
- core_process.ReadMemory(begin, size, error)
- self.assertTrue(error.Success(), error.GetCString())
+ expected_address_range = AddressRange(begin, end)
+ expected_invalid_range = AddressRange(begin - 16, end + 16)
+ self.validate_regions_saved_correctly(core_process, expected_address_range, expected_invalid_range)
def test_region_that_goes_out_of_bounds(self):
"""
@@ -105,13 +132,9 @@ def test_region_that_goes_out_of_bounds(self):
core_target = self.dbg.CreateTarget(None)
core_process = core_target.LoadCore(new_minidump_path)
- error = lldb.SBError()
- core_process.ReadMemory(begin, 0x00000020, error)
- self.assertTrue(error.Success(), error.GetCString())
-
- # Whole region should be unavailable
- core_process.ReadMemory(end, 1, error)
- self.assertTrue(error.Fail(), error.GetCString())
+ expected_address_range = AddressRange(begin, end)
+ expected_invalid_range = AddressRange(begin - 16, end + 16)
+ self.validate_regions_saved_correctly(core_process, expected_address_range, expected_invalid_range)
def test_region_that_starts_out_of_bounds(self):
"""
@@ -137,6 +160,6 @@ def test_region_that_starts_out_of_bounds(self):
core_target = self.dbg.CreateTarget(None)
core_process = core_target.LoadCore(new_minidump_path)
- error = lldb.SBError()
- core_process.ReadMemory(begin, 0x00000020, error)
- self.assertTrue(error.Success(), error.GetCString())
+ expected_address_range = AddressRange(begin, end)
+ expected_invalid_range = AddressRange(begin - 16, end)
+ self.validate_regions_saved_correctly(core_process, expected_address_range, expected_invalid_range)
diff --git a/lldb/test/API/functionalities/process_save_core_minidump/minidump_mem64.yaml b/lldb/test/API/functionalities/process_save_core_minidump/minidump_mem64.yaml
index 6c9c510b87a05..d9ada688692e5 100644
--- a/lldb/test/API/functionalities/process_save_core_minidump/minidump_mem64.yaml
+++ b/lldb/test/API/functionalities/process_save_core_minidump/minidump_mem64.yaml
@@ -27,7 +27,7 @@ Streams:
Data Size: 0x20
Content : ''
- Start of Memory Range: 0x3000
- Data Size: 0x4000
+ Data Size: 0x400
Content : ''
- Start of Memory Range: 0x5000
Data Size: 0x2000
>From 510cca89545ecade240a6fa496ab0ef19d537202 Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalonde at fb.com>
Date: Fri, 2 May 2025 08:43:32 -0700
Subject: [PATCH 6/7] Add test for a region that covers more than one actual
region, plus one that takes a full region and a sub range of a second region
---
.../TestProcessSaveCoreMinidumpYaml.py | 114 +++++++++++++++---
.../minidump_mem64.yaml | 5 +-
2 files changed, 98 insertions(+), 21 deletions(-)
diff --git a/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidumpYaml.py b/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidumpYaml.py
index f629e3536b186..eac36299bb71b 100644
--- a/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidumpYaml.py
+++ b/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidumpYaml.py
@@ -9,6 +9,7 @@
from lldbsuite.test import lldbutil
from dataclass import dataclass
+
class AddressRange:
begin: int
end: int
@@ -26,27 +27,35 @@ def process_from_yaml(self, yaml_file):
self.process = self.target.LoadCore(minidump_path)
return self.process
- def validate_regions_saved_correctly(self, core_process, expected_region, expected_invalid_region=None):
- """ Validate that the expected_region is saved in the core_proc, and that the expected invalid region is not saved, if not not none. """
+ def validate_regions_saved_correctly(
+ self, core_process, expected_region, expected_invalid_region=None
+ ):
+ """Validate that the expected_region is saved in the core_proc, and that the expected invalid region is not saved, if not not none."""
- # Validate we can read the entire expected_region
- error = lldb.SBError()
- core_process.ReadMemory(expected_region.begin, expected_region.end - expected_region.begin, error)
- self.assertTrue(error.Success(), error.GetCString())
+ # Validate we can read the entire expected_region
+ error = lldb.SBError()
+ core_process.ReadMemory(
+ expected_region.begin, expected_region.end - expected_region.begin, error
+ )
+ self.assertTrue(error.Success(), error.GetCString())
- # Validate we can't read before and after the expected_region
- core_process.ReadMemory(expected_region.begin - 1, 1, error)
- self.assertTrue(error.Fail(), error.GetCString())
+ # Validate we can't read before and after the expected_region
+ core_process.ReadMemory(expected_region.begin - 1, 1, error)
+ self.assertTrue(error.Fail(), error.GetCString())
- core_process.ReadMemory(expected_region.end + 1, 1, error)
- self.assertTrue(error.Fail(), error.GetCString())
+ core_process.ReadMemory(expected_region.end + 1, 1, error)
+ self.assertTrue(error.Fail(), error.GetCString())
- if expected_invalid_region is None:
- return
+ if expected_invalid_region is None:
+ return
- # Validate we can't read the original_region
- core_process.ReadMemory(expected_invalid_region.begin, expected_invalid_region.end - expected_invalid_region.end, error)
- self.assertTrue(error.Success(), error.GetCString())
+ # Validate we can't read the original_region
+ core_process.ReadMemory(
+ expected_invalid_region.begin,
+ expected_invalid_region.end - expected_invalid_region.end,
+ error,
+ )
+ self.assertTrue(error.Success(), error.GetCString())
def test_saving_sub_memory_range(self):
"""
@@ -76,7 +85,9 @@ def test_saving_sub_memory_range(self):
expected_address_range = AddressRange(begin, end)
expected_invalid_range = AddressRange(begin, 0x2020)
- self.validate_regions_saved_correctly(core_process, expected_address_range, expected_invalid_range)
+ self.validate_regions_saved_correctly(
+ core_process, expected_address_range, expected_invalid_range
+ )
def test_saving_super_memory_range(self):
"""
@@ -106,7 +117,9 @@ def test_saving_super_memory_range(self):
expected_address_range = AddressRange(begin, end)
expected_invalid_range = AddressRange(begin - 16, end + 16)
- self.validate_regions_saved_correctly(core_process, expected_address_range, expected_invalid_range)
+ self.validate_regions_saved_correctly(
+ core_process, expected_address_range, expected_invalid_range
+ )
def test_region_that_goes_out_of_bounds(self):
"""
@@ -134,7 +147,9 @@ def test_region_that_goes_out_of_bounds(self):
expected_address_range = AddressRange(begin, end)
expected_invalid_range = AddressRange(begin - 16, end + 16)
- self.validate_regions_saved_correctly(core_process, expected_address_range, expected_invalid_range)
+ self.validate_regions_saved_correctly(
+ core_process, expected_address_range, expected_invalid_range
+ )
def test_region_that_starts_out_of_bounds(self):
"""
@@ -162,4 +177,63 @@ def test_region_that_starts_out_of_bounds(self):
expected_address_range = AddressRange(begin, end)
expected_invalid_range = AddressRange(begin - 16, end)
- self.validate_regions_saved_correctly(core_process, expected_address_range, expected_invalid_range)
+ self.validate_regions_saved_correctly(
+ core_process, expected_address_range, expected_invalid_range
+ )
+
+ def test_region_spans_multiple_regions(self):
+ """
+ Validate we can save a Minidump for a custom region
+ that includes a start in a (---) page but ends in a valid page.
+ """
+ yaml = "minidump_mem64.yaml"
+ proc = self.process_from_yaml(yaml)
+ new_minidump_path = self.getBuildArtifact(__name__ + ".dmp")
+ options = lldb.SBSaveCoreOptions()
+ options.SetOutputFile(lldb.SBFileSpec(new_minidump_path))
+ options.SetPluginName("minidump")
+ options.SetStyle(lldb.eSaveCoreCustomOnly)
+
+ size = 0x1000
+ begin = 0x5000
+ end = begin + size
+ custom_range = lldb.SBMemoryRegionInfo("", begin, end, 3, True, False)
+ options.AddMemoryRegionToSave(custom_range)
+
+ error = proc.SaveCore(options)
+ self.assertTrue(error.Success(), error.GetCString())
+ core_target = self.dbg.CreateTarget(None)
+ core_process = core_target.LoadCore(new_minidump_path)
+
+ expected_address_range = AddressRange(begin, end)
+ self.validate_regions_saved_correctly(core_process, expected_address_range)
+
+ def test_region_spans_multiple_regions_with_one_subrange(self):
+ """
+ Validate we can save a Minidump for a custom region
+ that includes a start in a (---) page but ends in a valid page.
+ """
+ yaml = "minidump_mem64.yaml"
+ proc = self.process_from_yaml(yaml)
+ new_minidump_path = self.getBuildArtifact(__name__ + ".dmp")
+ options = lldb.SBSaveCoreOptions()
+ options.SetOutputFile(lldb.SBFileSpec(new_minidump_path))
+ options.SetPluginName("minidump")
+ options.SetStyle(lldb.eSaveCoreCustomOnly)
+
+ size = 0x800
+ begin = 0x5000
+ end = begin + size
+ custom_range = lldb.SBMemoryRegionInfo("", begin, end, 3, True, False)
+ options.AddMemoryRegionToSave(custom_range)
+
+ error = proc.SaveCore(options)
+ self.assertTrue(error.Success(), error.GetCString())
+ core_target = self.dbg.CreateTarget(None)
+ core_process = core_target.LoadCore(new_minidump_path)
+
+ expected_address_range = AddressRange(begin, end)
+ expected_invalid_range = AddressRange(begin, begin + 0x1000)
+ self.validate_regions_saved_correctly(
+ core_process, expected_address_range, expected_invalid_range
+ )
diff --git a/lldb/test/API/functionalities/process_save_core_minidump/minidump_mem64.yaml b/lldb/test/API/functionalities/process_save_core_minidump/minidump_mem64.yaml
index d9ada688692e5..d04ca1ae0dc12 100644
--- a/lldb/test/API/functionalities/process_save_core_minidump/minidump_mem64.yaml
+++ b/lldb/test/API/functionalities/process_save_core_minidump/minidump_mem64.yaml
@@ -30,6 +30,9 @@ Streams:
Data Size: 0x400
Content : ''
- Start of Memory Range: 0x5000
- Data Size: 0x2000
+ Data Size: 0x500
+ Content : ''
+ - Start of Memory Range: 0x5500
+ Data Size: 0x500
Content : ''
...
>From 31553f54b6f56e08d99093655b896032c7954d3f Mon Sep 17 00:00:00 2001
From: Jacob Lalonde <jalalonde at fb.com>
Date: Fri, 2 May 2025 12:50:46 -0700
Subject: [PATCH 7/7] Fix bug with the test helper method
---
.../TestProcessSaveCoreMinidumpYaml.py | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidumpYaml.py b/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidumpYaml.py
index eac36299bb71b..afa5baf23c958 100644
--- a/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidumpYaml.py
+++ b/lldb/test/API/functionalities/process_save_core_minidump/TestProcessSaveCoreMinidumpYaml.py
@@ -7,7 +7,6 @@
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
-from dataclass import dataclass
class AddressRange:
@@ -52,10 +51,10 @@ def validate_regions_saved_correctly(
# Validate we can't read the original_region
core_process.ReadMemory(
expected_invalid_region.begin,
- expected_invalid_region.end - expected_invalid_region.end,
+ expected_invalid_region.end - expected_invalid_region.begin,
error,
)
- self.assertTrue(error.Success(), error.GetCString())
+ self.assertTrue(error.Fail(), error.GetCString())
def test_saving_sub_memory_range(self):
"""
More information about the lldb-commits
mailing list