Skip to content

Commit 91ce099

Browse files
committed
Change custom regions to be intersections, add test cases for sub regions and super regions, plus changes of permissions and invalid pages.
1 parent 7d4e6ff commit 91ce099

File tree

4 files changed

+223
-3
lines changed

4 files changed

+223
-3
lines changed

lldb/include/lldb/Utility/RangeMap.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,25 @@ template <typename B, typename S, unsigned N = 0> class RangeVector {
380380
return nullptr;
381381
}
382382

383+
const Entry* FindEntryThatIntersects(const Entry &range) const {
384+
#ifdef ASSERT_RANGEMAP_ARE_SORTED
385+
assert(IsSorted());
386+
#endif
387+
if (!m_entries.empty()) {
388+
typename Collection::const_iterator begin = m_entries.begin();
389+
typename Collection::const_iterator end = m_entries.end();
390+
typename Collection::const_iterator pos =
391+
std::lower_bound(begin, end, range, BaseLessThan);
392+
393+
while (pos != begin && pos[-1].DoesIntersect(range))
394+
--pos;
395+
396+
if (pos != end && pos->DoesIntersect(range))
397+
return &(*pos);
398+
}
399+
return nullptr;
400+
}
401+
383402
using const_iterator = typename Collection::const_iterator;
384403
const_iterator begin() const { return m_entries.begin(); }
385404
const_iterator end() const { return m_entries.end(); }

lldb/source/Target/Process.cpp

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6689,6 +6689,23 @@ static void GetCoreFileSaveRangesStackOnly(Process &process,
66896689
}
66906690
}
66916691

6692+
// TODO: We should refactor CoreFileMemoryRanges to use the lldb range type, and then
6693+
// add an intersect method on it, or MemoryRegionInfo.
6694+
static MemoryRegionInfo Intersect(const MemoryRegionInfo &lhs, const Range<lldb::addr_t, lldb::addr_t> &rhs) {
6695+
const lldb::addr_t lhs_base = lhs.GetRange().GetRangeBase();
6696+
const lldb::addr_t rhs_base = rhs.GetRangeBase();
6697+
const lldb::addr_t lhs_end = lhs.GetRange().GetRangeEnd();
6698+
const lldb::addr_t rhs_end = rhs.GetRangeEnd();
6699+
6700+
MemoryRegionInfo region_info;
6701+
region_info.SetLLDBPermissions(lhs.GetLLDBPermissions());
6702+
auto &range = region_info.GetRange();
6703+
range.SetRangeBase(std::max(lhs_base, rhs_base));
6704+
range.SetRangeEnd(std::min(lhs_end, rhs_end));
6705+
6706+
return region_info;
6707+
}
6708+
66926709
static void GetUserSpecifiedCoreFileSaveRanges(Process &process,
66936710
const MemoryRegionInfos &regions,
66946711
const SaveCoreOptions &options,
@@ -6698,9 +6715,16 @@ static void GetUserSpecifiedCoreFileSaveRanges(Process &process,
66986715
return;
66996716

67006717
for (const auto &range : regions) {
6701-
auto entry = option_ranges.FindEntryThatContains(range.GetRange());
6702-
if (entry)
6703-
AddRegion(range, true, ranges);
6718+
auto *entry = option_ranges.FindEntryThatIntersects(range.GetRange());
6719+
if (entry) {
6720+
if (entry->GetRangeBase() != range.GetRange().GetRangeBase()
6721+
|| entry->GetRangeEnd() != range.GetRange().GetRangeEnd()) {
6722+
AddRegion(Intersect(range, *entry), true, ranges);
6723+
} else {
6724+
// If they match, add the range directly.
6725+
AddRegion(range, true, ranges);
6726+
}
6727+
}
67046728
}
67056729
}
67066730

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
"""
2+
Test saving a mini dump, from yamilized examples.
3+
"""
4+
5+
import os
6+
import lldb
7+
from lldbsuite.test.decorators import *
8+
from lldbsuite.test.lldbtest import *
9+
from lldbsuite.test import lldbutil
10+
11+
class ProcessSaveCoreMinidumpTestCaseYaml(TestBase):
12+
def process_from_yaml(self, yaml_file):
13+
minidump_path = self.getBuildArtifact(os.path.basename(yaml_file) + ".dmp")
14+
self.yaml2obj(yaml_file, minidump_path)
15+
self.target = self.dbg.CreateTarget(None)
16+
self.process = self.target.LoadCore(minidump_path)
17+
return self.process
18+
19+
def test_saving_sub_memory_range(self):
20+
"""
21+
Validate we can save a Minidump for a subsection of a memory range.
22+
I.E.
23+
If our memory range is 0x1000-0x2000 nd the user specifies 0x1200-0x1800
24+
we should still capture 0x1200 to 0x1800
25+
"""
26+
yaml = "minidump_mem64.yaml"
27+
proc = self.process_from_yaml(yaml)
28+
new_minidump_path = self.getBuildArtifact(__name__ + ".dmp")
29+
options = lldb.SBSaveCoreOptions()
30+
options.SetOutputFile(lldb.SBFileSpec(new_minidump_path))
31+
options.SetPluginName("minidump")
32+
options.SetStyle(lldb.eSaveCoreCustomOnly)
33+
34+
size = 8
35+
begin = 0x7FFF12A84030
36+
end = begin + size
37+
custom_range = lldb.SBMemoryRegionInfo("", begin, end, 3, True, False)
38+
options.AddMemoryRegionToSave(custom_range)
39+
40+
error = proc.SaveCore(options)
41+
self.assertTrue(error.Success(), error.GetCString())
42+
core_target = self.dbg.CreateTarget(None)
43+
core_process = core_target.LoadCore(new_minidump_path)
44+
45+
error = lldb.SBError()
46+
core_process.ReadMemory(begin, size, error)
47+
self.assertTrue(error.Success(), error.GetCString())
48+
49+
# Try to read 1 byte past the end
50+
core_process.ReadMemory(end + 1, 1, error)
51+
self.assertTrue(error.Fail(), error.GetCString())
52+
53+
def test_saving_super_memory_range(self):
54+
"""
55+
Validate we can save a Minidump for a subsection of a memory range.
56+
I.E.
57+
If our memory range is 0x1000-0x2000 nd the user specifies 0x0800-0x2800
58+
we should still capture 0x1000-0x2000
59+
"""
60+
yaml = "minidump_mem64.yaml"
61+
proc = self.process_from_yaml(yaml)
62+
new_minidump_path = self.getBuildArtifact(__name__ + ".dmp")
63+
options = lldb.SBSaveCoreOptions()
64+
options.SetOutputFile(lldb.SBFileSpec(new_minidump_path))
65+
options.SetPluginName("minidump")
66+
options.SetStyle(lldb.eSaveCoreCustomOnly)
67+
68+
size = 0x2FD0
69+
begin = 0x7FFF12A84030
70+
end = begin + size
71+
custom_range = lldb.SBMemoryRegionInfo("", begin - 16, end + 16, 3, True, False)
72+
options.AddMemoryRegionToSave(custom_range)
73+
74+
error = proc.SaveCore(options)
75+
self.assertTrue(error.Success(), error.GetCString())
76+
core_target = self.dbg.CreateTarget(None)
77+
core_process = core_target.LoadCore(new_minidump_path)
78+
79+
error = lldb.SBError()
80+
core_process.ReadMemory(begin, size, error)
81+
self.assertTrue(error.Success(), error.GetCString())
82+
83+
84+
def test_region_that_goes_out_of_bounds(self):
85+
"""
86+
Validate we can save a Minidump for a custom region
87+
that includes an end that enters an invalid (---) page.
88+
"""
89+
yaml = "minidump_mem64.yaml"
90+
proc = self.process_from_yaml(yaml)
91+
new_minidump_path = self.getBuildArtifact(__name__ + ".dmp")
92+
options = lldb.SBSaveCoreOptions()
93+
options.SetOutputFile(lldb.SBFileSpec(new_minidump_path))
94+
options.SetPluginName("minidump")
95+
options.SetStyle(lldb.eSaveCoreCustomOnly)
96+
97+
size = 1024
98+
begin = 0x00007fff12a8ffff
99+
end = begin + size
100+
custom_range = lldb.SBMemoryRegionInfo("", begin, end, 3, True, False)
101+
options.AddMemoryRegionToSave(custom_range)
102+
103+
error = proc.SaveCore(options)
104+
self.assertTrue(error.Success(), error.GetCString())
105+
core_target = self.dbg.CreateTarget(None)
106+
core_process = core_target.LoadCore(new_minidump_path)
107+
108+
error = lldb.SBError()
109+
core_process.ReadMemory(begin, 0x00000020, error)
110+
self.assertTrue(error.Success(), error.GetCString())
111+
112+
# Whole region should be unavailable
113+
core_process.ReadMemory(end, 1, error)
114+
self.assertTrue(error.Fail(), error.GetCString())
115+
116+
def test_region_that_starts_out_of_bounds(self):
117+
"""
118+
Validate we can save a Minidump for a custom region
119+
that includes a start in a (---) page but ends in a valid page.
120+
"""
121+
yaml = "minidump_mem64.yaml"
122+
proc = self.process_from_yaml(yaml)
123+
new_minidump_path = self.getBuildArtifact(__name__ + ".dmp")
124+
options = lldb.SBSaveCoreOptions()
125+
options.SetOutputFile(lldb.SBFileSpec(new_minidump_path))
126+
options.SetPluginName("minidump")
127+
options.SetStyle(lldb.eSaveCoreCustomOnly)
128+
129+
size = 0x00000020
130+
begin = 0x00007fff12a8ffff
131+
end = begin + size
132+
custom_range = lldb.SBMemoryRegionInfo("", begin - 16, end, 3, True, False)
133+
options.AddMemoryRegionToSave(custom_range)
134+
135+
error = proc.SaveCore(options)
136+
self.assertTrue(error.Success(), error.GetCString())
137+
core_target = self.dbg.CreateTarget(None)
138+
core_process = core_target.LoadCore(new_minidump_path)
139+
140+
error = lldb.SBError()
141+
core_process.ReadMemory(begin, 0x00000020, error)
142+
self.assertTrue(error.Success(), error.GetCString())
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
--- !minidump
2+
Streams:
3+
- Type: SystemInfo
4+
Processor Arch: AMD64
5+
Processor Level: 6
6+
Processor Revision: 15876
7+
Number of Processors: 40
8+
Platform ID: Linux
9+
CSD Version: 'Linux 3.13.0-91-generic'
10+
CPU:
11+
Vendor ID: GenuineIntel
12+
Version Info: 0x00000000
13+
Feature Info: 0x00000000
14+
- Type: ThreadList
15+
Threads:
16+
- Thread Id: 0x2896BB
17+
Context: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000700100000000000FFFFFFFF0000FFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000B040A812FF7F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000050D0A75BBA7F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
18+
Stack:
19+
Start of Memory Range: 0x0
20+
Content: ''
21+
- Type: Memory64List
22+
Memory Ranges:
23+
- Start of Memory Range: 0x7FFF12A84030
24+
Data Size: 0x2FD0
25+
Content : ''
26+
- Start of Memory Range: 0x00007fff12a87000
27+
Data Size: 0x00000018
28+
Content : ''
29+
- Start of Memory Range: 0x00007fff12a87018
30+
Data Size: 0x00000400
31+
Content : ''
32+
- Start of Memory Range: 0x00007fff12a8ffff
33+
Data Size: 0x00000020
34+
Content : ''
35+
...

0 commit comments

Comments
 (0)