xref: /llvm-project/lldb/test/API/functionalities/memory/holes/TestMemoryHoles.py (revision cc5c526c80a4cacf7ed5b7fbe50072594ec1aeaf)
1181cc75eSPavel Labath"""
2181cc75eSPavel LabathTest the memory commands operating on memory regions with holes (inaccessible
3181cc75eSPavel Labathpages)
4181cc75eSPavel Labath"""
5181cc75eSPavel Labath
6181cc75eSPavel Labathimport lldb
7181cc75eSPavel Labathfrom lldbsuite.test.lldbtest import *
8181cc75eSPavel Labathimport lldbsuite.test.lldbutil as lldbutil
9181cc75eSPavel Labathfrom lldbsuite.test.decorators import *
10181cc75eSPavel Labath
11181cc75eSPavel Labath
12181cc75eSPavel Labathclass MemoryHolesTestCase(TestBase):
13181cc75eSPavel Labath    NO_DEBUG_INFO_TESTCASE = True
14181cc75eSPavel Labath
15181cc75eSPavel Labath    def setUp(self):
16181cc75eSPavel Labath        super().setUp()
17181cc75eSPavel Labath        # Find the line number to break inside main().
18181cc75eSPavel Labath        self.line = line_number("main.cpp", "// break here")
19181cc75eSPavel Labath
20181cc75eSPavel Labath    def _prepare_inferior(self):
21181cc75eSPavel Labath        self.build()
22181cc75eSPavel Labath        exe = self.getBuildArtifact("a.out")
23181cc75eSPavel Labath        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
24181cc75eSPavel Labath
25181cc75eSPavel Labath        # Break in main() after the variables are assigned values.
26181cc75eSPavel Labath        lldbutil.run_break_set_by_file_and_line(
27181cc75eSPavel Labath            self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True
28181cc75eSPavel Labath        )
29181cc75eSPavel Labath
30181cc75eSPavel Labath        self.runCmd("run", RUN_SUCCEEDED)
31181cc75eSPavel Labath
32181cc75eSPavel Labath        # The stop reason of the thread should be breakpoint.
33181cc75eSPavel Labath        self.expect(
34181cc75eSPavel Labath            "thread list",
35181cc75eSPavel Labath            STOPPED_DUE_TO_BREAKPOINT,
36181cc75eSPavel Labath            substrs=["stopped", "stop reason = breakpoint"],
37181cc75eSPavel Labath        )
38181cc75eSPavel Labath
39181cc75eSPavel Labath        # The breakpoint should have a hit count of 1.
40181cc75eSPavel Labath        lldbutil.check_breakpoint(self, bpno=1, expected_hit_count=1)
41181cc75eSPavel Labath
42181cc75eSPavel Labath        # Avoid the expression evaluator, as it can allocate allocate memory
43181cc75eSPavel Labath        # inside the holes we've deliberately left empty.
44181cc75eSPavel Labath        self.memory = self.frame().FindVariable("mem_with_holes").GetValueAsUnsigned()
45181cc75eSPavel Labath        self.pagesize = self.frame().FindVariable("pagesize").GetValueAsUnsigned()
46*cc5c526cSPavel Labath        self.num_pages = (
47*cc5c526cSPavel Labath            self.target().FindFirstGlobalVariable("num_pages").GetValueAsUnsigned()
48*cc5c526cSPavel Labath        )
49181cc75eSPavel Labath        positions = self.frame().FindVariable("positions")
50181cc75eSPavel Labath        self.positions = [
51181cc75eSPavel Labath            positions.GetChildAtIndex(i).GetValueAsUnsigned()
52181cc75eSPavel Labath            for i in range(positions.GetNumChildren())
53181cc75eSPavel Labath        ]
54181cc75eSPavel Labath        self.assertEqual(len(self.positions), 5)
55181cc75eSPavel Labath
56181cc75eSPavel Labath    def test_memory_read(self):
57181cc75eSPavel Labath        self._prepare_inferior()
58181cc75eSPavel Labath
59181cc75eSPavel Labath        error = lldb.SBError()
60181cc75eSPavel Labath        content = self.process().ReadMemory(self.memory, 2 * self.pagesize, error)
61181cc75eSPavel Labath        self.assertEqual(len(content), self.pagesize)
62181cc75eSPavel Labath        self.assertEqual(content[0:7], b"needle\0")
63181cc75eSPavel Labath        self.assertTrue(error.Fail())
64*cc5c526cSPavel Labath
65*cc5c526cSPavel Labath    def test_memory_find(self):
66*cc5c526cSPavel Labath        self._prepare_inferior()
67*cc5c526cSPavel Labath
68*cc5c526cSPavel Labath        matches = [f"data found at location: {p:#x}" for p in self.positions]
69*cc5c526cSPavel Labath        self.expect(
70*cc5c526cSPavel Labath            f'memory find --count {len(self.positions)+1} --string "needle" '
71*cc5c526cSPavel Labath            f"{self.memory:#x} {self.memory+self.pagesize*self.num_pages:#x}",
72*cc5c526cSPavel Labath            substrs=matches + ["no more matches within the range"],
73*cc5c526cSPavel Labath        )
74