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