| """ | |
| Test SBAddressRange APIs. | |
| """ | |
| import lldb | |
| from lldbsuite.test.lldbtest import * | |
| class AddressRangeTestCase(TestBase): | |
| NO_DEBUG_INFO_TESTCASE = True | |
| def setUp(self): | |
| TestBase.setUp(self) | |
| self.build() | |
| exe = self.getBuildArtifact("a.out") | |
| self.target = self.dbg.CreateTarget(exe) | |
| self.assertTrue(self.target, VALID_TARGET) | |
| self.launch_info = self.target.GetLaunchInfo() | |
| self.launch_info.SetWorkingDirectory(self.get_process_working_directory()) | |
| self.bp1 = self.target.BreakpointCreateByName("main", "a.out") | |
| self.bp2 = self.target.BreakpointCreateByName("foo", "a.out") | |
| self.bp3 = self.target.BreakpointCreateByName("bar", "a.out") | |
| self.assertTrue(self.bp1.IsValid()) | |
| self.assertTrue(self.bp2.IsValid()) | |
| self.assertTrue(self.bp3.IsValid()) | |
| self.addr1 = self.bp1.GetLocationAtIndex(0).GetAddress() | |
| self.addr2 = self.bp2.GetLocationAtIndex(0).GetAddress() | |
| self.addr3 = self.bp3.GetLocationAtIndex(0).GetAddress() | |
| self.assertTrue(self.addr1.IsValid()) | |
| self.assertTrue(self.addr2.IsValid()) | |
| self.assertTrue(self.addr3.IsValid()) | |
| def test_address_range_default(self): | |
| """Testing default constructor.""" | |
| empty_range = lldb.SBAddressRange() | |
| self.assertEqual(empty_range.IsValid(), False) | |
| def test_address_range_construction(self): | |
| """Make sure the construction and getters work.""" | |
| range = lldb.SBAddressRange(self.addr1, 8) | |
| self.assertEqual(range.IsValid(), True) | |
| self.assertEqual(range.GetBaseAddress(), self.addr1) | |
| self.assertEqual(range.GetByteSize(), 8) | |
| def test_address_range_clear(self): | |
| """Make sure the clear method works.""" | |
| range = lldb.SBAddressRange(self.addr1, 8) | |
| self.assertEqual(range.IsValid(), True) | |
| self.assertEqual(range.GetBaseAddress(), self.addr1) | |
| self.assertEqual(range.GetByteSize(), 8) | |
| range.Clear() | |
| self.assertEqual(range.IsValid(), False) | |
| def test_function(self): | |
| """Make sure the range works in SBFunction APIs.""" | |
| # Setup breakpoints in main | |
| loc = self.bp1.GetLocationAtIndex(0) | |
| loc_addr = loc.GetAddress() | |
| func = loc_addr.GetFunction() | |
| ranges = func.GetRanges() | |
| self.assertEqual(ranges.GetSize(), 1) | |
| range = ranges.GetAddressRangeAtIndex(0) | |
| self.assertEqual( | |
| range.GetByteSize(), | |
| func.GetEndAddress().GetOffset() - func.GetStartAddress().GetOffset(), | |
| ) | |
| self.assertEqual( | |
| range.GetBaseAddress().GetOffset(), | |
| func.GetStartAddress().GetOffset(), | |
| ) | |
| def test_block(self): | |
| """Make sure the range works in SBBlock APIs.""" | |
| loc = self.bp1.GetLocationAtIndex(0) | |
| loc_addr = loc.GetAddress() | |
| block = loc_addr.GetBlock() | |
| ranges = block.GetRanges() | |
| self.assertEqual(ranges.GetSize(), 1) | |
| range = ranges.GetAddressRangeAtIndex(0) | |
| self.assertEqual( | |
| range.GetByteSize(), | |
| block.GetRangeEndAddress(0).GetOffset() | |
| - block.GetRangeStartAddress(0).GetOffset(), | |
| ) | |
| self.assertEqual( | |
| range.GetBaseAddress().GetOffset(), | |
| block.GetRangeStartAddress(0).GetOffset(), | |
| ) | |
| def test_address_range_list(self): | |
| """Make sure the SBAddressRangeList works by adding and getting ranges.""" | |
| range1 = lldb.SBAddressRange(self.addr1, 8) | |
| range2 = lldb.SBAddressRange(self.addr2, 16) | |
| range3 = lldb.SBAddressRange(self.addr3, 32) | |
| range_list = lldb.SBAddressRangeList() | |
| self.assertEqual(range_list.GetSize(), 0) | |
| range_list.Append(range1) | |
| range_list.Append(range2) | |
| range_list.Append(range3) | |
| self.assertEqual(range_list.GetSize(), 3) | |
| self.assertRaises(IndexError, lambda: range_list[3]) | |
| range1_copy = range_list.GetAddressRangeAtIndex(0) | |
| self.assertEqual(range1.GetByteSize(), range1_copy.GetByteSize()) | |
| self.assertEqual( | |
| range1.GetBaseAddress().GetOffset(), | |
| range1_copy.GetBaseAddress().GetOffset(), | |
| ) | |
| range2_copy = range_list.GetAddressRangeAtIndex(1) | |
| self.assertEqual(range2.GetByteSize(), range2_copy.GetByteSize()) | |
| self.assertEqual( | |
| range2.GetBaseAddress().GetOffset(), | |
| range2_copy.GetBaseAddress().GetOffset(), | |
| ) | |
| range3_copy = range_list.GetAddressRangeAtIndex(2) | |
| self.assertEqual(range3.GetByteSize(), range3_copy.GetByteSize()) | |
| self.assertEqual( | |
| range3.GetBaseAddress().GetOffset(), | |
| range3_copy.GetBaseAddress().GetOffset(), | |
| ) | |
| range_list.Clear() | |
| self.assertEqual(range_list.GetSize(), 0) | |
| def test_address_range_list_len(self): | |
| """Make sure the len() operator works.""" | |
| range = lldb.SBAddressRange(self.addr1, 8) | |
| range_list = lldb.SBAddressRangeList() | |
| self.assertEqual(len(range_list), 0) | |
| range_list.Append(range) | |
| self.assertEqual(len(range_list), 1) | |
| def test_address_range_list_iterator(self): | |
| """Make sure the SBAddressRangeList iterator works.""" | |
| range1 = lldb.SBAddressRange(self.addr1, 8) | |
| range2 = lldb.SBAddressRange(self.addr2, 16) | |
| range3 = lldb.SBAddressRange(self.addr3, 32) | |
| range_list = lldb.SBAddressRangeList() | |
| range_list.Append(range1) | |
| range_list.Append(range2) | |
| range_list.Append(range3) | |
| self.assertEqual(range_list.GetSize(), 3) | |
| # Test the iterator | |
| for range in range_list: | |
| self.assertTrue(range.IsValid()) | |
| def test_address_range_print_invalid(self): | |
| """Make sure the SBAddressRange can be printed when invalid.""" | |
| range = lldb.SBAddressRange() | |
| self.assertEqual(str(range), "[0xffffffffffffffff-0xffffffffffffffff)") | |
| def test_address_range_print_resolved(self): | |
| """Make sure the SBAddressRange can be printed when resolved.""" | |
| lldb.target = self.target | |
| error = lldb.SBError() | |
| process = self.target.Launch(self.launch_info, error) | |
| self.assertTrue(error.Success(), "Make sure process launched successfully") | |
| self.assertTrue(process, PROCESS_IS_VALID) | |
| self.assertState(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) | |
| script = ( | |
| "script " | |
| + "bp = lldb.target.GetBreakpointAtIndex(0);" | |
| + "loc = bp.GetLocationAtIndex(0);" | |
| + "loc_addr = loc.GetAddress();" | |
| + "func = loc_addr.GetFunction();" | |
| + "range = func.GetRanges().GetAddressRangeAtIndex(0);" | |
| + "print(range)" | |
| ) | |
| interp = self.dbg.GetCommandInterpreter() | |
| result = lldb.SBCommandReturnObject() | |
| interp.HandleCommand(script, result, False) | |
| self.assertTrue(result.Succeeded(), "script command succeeded") | |
| # [0x1000-0x2000] // Resolved with target or addresses without sections | |
| self.assertRegex(result.GetOutput(), r"^\[0x[0-9a-f]+\-0x[0-9a-f]+\)") | |
| process.Kill() | |
| def test_address_range_print_no_section_resolved(self): | |
| """Make sure the SBAddressRange can be printed with no secion.""" | |
| lldb.target = self.target | |
| error = lldb.SBError() | |
| process = self.target.Launch(self.launch_info, error) | |
| self.assertTrue(error.Success(), "Make sure process launched successfully") | |
| self.assertTrue(process, PROCESS_IS_VALID) | |
| self.assertState(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) | |
| loc = self.bp1.GetLocationAtIndex(0) | |
| loc_addr = loc.GetAddress() | |
| func = loc_addr.GetFunction() | |
| range = func.GetRanges().GetAddressRangeAtIndex(0) | |
| addr = lldb.SBAddress() | |
| addr.SetAddress(lldb.SBSection(), range.GetBaseAddress().GetOffset()) | |
| self.assertFalse(addr.GetSection().IsValid()) | |
| range = lldb.SBAddressRange(addr, range.GetByteSize()) | |
| range_str = str(range) | |
| # [0x1000-0x2000] // Resolved with target or addresses without sections | |
| self.assertRegex(range_str, r"^\[0x[0-9a-f]+\-0x[0-9a-f]+\)$") | |
| process.Kill() | |
| def test_address_range_print_not_resolved(self): | |
| """Make sure the SBAddressRange can be printed when not resolved.""" | |
| range = lldb.SBAddressRange(self.addr1, 8) | |
| range_str = str(range) | |
| # a.out[0x1000-0x2000] // Without target | |
| self.assertRegex(range_str, r"^a.out\[0x[0-9a-f]+\-0x[0-9a-f]+\)$") | |
| def test_address_range_list_print(self): | |
| """Make sure the SBAddressRangeList can be printed.""" | |
| range1 = lldb.SBAddressRange(self.addr1, 8) | |
| range2 = lldb.SBAddressRange(self.addr2, 16) | |
| range3 = lldb.SBAddressRange(self.addr3, 32) | |
| self.dbg.SetAsync(True) | |
| range_list = lldb.SBAddressRangeList() | |
| self.assertEqual(range_list.GetSize(), 0) | |
| range_list.Append(range1) | |
| range_list.Append(range2) | |
| range_list.Append(range3) | |
| self.assertEqual(range_list.GetSize(), 3) | |
| range_list_str = str(range_list) | |
| self.assertTrue(range_list_str.startswith("[")) | |
| self.assertGreater(range_list_str.count(","), 1) | |
| self.assertTrue(range_list_str.endswith("]")) | |
| def test_address_range_list_indexing(self): | |
| """Make sure the SBAddressRangeList can be printed.""" | |
| range1 = lldb.SBAddressRange(self.addr1, 8) | |
| range2 = lldb.SBAddressRange(self.addr2, 16) | |
| range_list = lldb.SBAddressRangeList() | |
| range_list.Append(range1) | |
| range_list.Append(range2) | |
| self.assertEqual(range_list.GetSize(), 2) | |
| self.assertRaises(IndexError, lambda: range_list[2]) | |
| self.assertRaises(TypeError, lambda: range_list["0"]) | |
| self.assertEqual(range_list[0], range1) | |
| self.assertEqual(range_list[1], range2) | |
| self.assertEqual(range_list[-1], range2) | |
| self.assertEqual(range_list[-2], range1) |