xref: /llvm-project/lldb/test/API/python_api/address_range/TestAddressRange.py (revision a083e50f53f0f9eb9ad0c5b65f3c627cf97043e6)
1"""
2Test SBAddressRange APIs.
3"""
4
5import lldb
6from lldbsuite.test.lldbtest import *
7
8
9class AddressRangeTestCase(TestBase):
10    NO_DEBUG_INFO_TESTCASE = True
11
12    def setUp(self):
13        TestBase.setUp(self)
14
15        self.build()
16        exe = self.getBuildArtifact("a.out")
17
18        self.target = self.dbg.CreateTarget(exe)
19        self.assertTrue(self.target, VALID_TARGET)
20        self.launch_info = self.target.GetLaunchInfo()
21        self.launch_info.SetWorkingDirectory(self.get_process_working_directory())
22
23        self.bp1 = self.target.BreakpointCreateByName("main", "a.out")
24        self.bp2 = self.target.BreakpointCreateByName("foo", "a.out")
25        self.bp3 = self.target.BreakpointCreateByName("bar", "a.out")
26
27        self.assertTrue(self.bp1.IsValid())
28        self.assertTrue(self.bp2.IsValid())
29        self.assertTrue(self.bp3.IsValid())
30
31        self.addr1 = self.bp1.GetLocationAtIndex(0).GetAddress()
32        self.addr2 = self.bp2.GetLocationAtIndex(0).GetAddress()
33        self.addr3 = self.bp3.GetLocationAtIndex(0).GetAddress()
34
35        self.assertTrue(self.addr1.IsValid())
36        self.assertTrue(self.addr2.IsValid())
37        self.assertTrue(self.addr3.IsValid())
38
39    def test_address_range_default(self):
40        """Testing default constructor."""
41        empty_range = lldb.SBAddressRange()
42        self.assertEqual(empty_range.IsValid(), False)
43
44    def test_address_range_construction(self):
45        """Make sure the construction and getters work."""
46        range = lldb.SBAddressRange(self.addr1, 8)
47        self.assertEqual(range.IsValid(), True)
48        self.assertEqual(range.GetBaseAddress(), self.addr1)
49        self.assertEqual(range.GetByteSize(), 8)
50
51    def test_address_range_clear(self):
52        """Make sure the clear method works."""
53        range = lldb.SBAddressRange(self.addr1, 8)
54        self.assertEqual(range.IsValid(), True)
55        self.assertEqual(range.GetBaseAddress(), self.addr1)
56        self.assertEqual(range.GetByteSize(), 8)
57
58        range.Clear()
59        self.assertEqual(range.IsValid(), False)
60
61    def test_function(self):
62        """Make sure the range works in SBFunction APIs."""
63
64        # Setup breakpoints in main
65        loc = self.bp1.GetLocationAtIndex(0)
66        loc_addr = loc.GetAddress()
67        func = loc_addr.GetFunction()
68        ranges = func.GetRanges()
69        self.assertEqual(ranges.GetSize(), 1)
70
71        range = ranges.GetAddressRangeAtIndex(0)
72        self.assertEqual(
73            range.GetByteSize(),
74            func.GetEndAddress().GetOffset() - func.GetStartAddress().GetOffset(),
75        )
76        self.assertEqual(
77            range.GetBaseAddress().GetOffset(),
78            func.GetStartAddress().GetOffset(),
79        )
80
81    def test_block(self):
82        """Make sure the range works in SBBlock APIs."""
83        loc = self.bp1.GetLocationAtIndex(0)
84        loc_addr = loc.GetAddress()
85        block = loc_addr.GetBlock()
86
87        ranges = block.GetRanges()
88        self.assertEqual(ranges.GetSize(), 1)
89
90        range = ranges.GetAddressRangeAtIndex(0)
91        self.assertEqual(
92            range.GetByteSize(),
93            block.GetRangeEndAddress(0).GetOffset()
94            - block.GetRangeStartAddress(0).GetOffset(),
95        )
96        self.assertEqual(
97            range.GetBaseAddress().GetOffset(),
98            block.GetRangeStartAddress(0).GetOffset(),
99        )
100
101    def test_address_range_list(self):
102        """Make sure the SBAddressRangeList works by adding and getting ranges."""
103        range1 = lldb.SBAddressRange(self.addr1, 8)
104        range2 = lldb.SBAddressRange(self.addr2, 16)
105        range3 = lldb.SBAddressRange(self.addr3, 32)
106
107        range_list = lldb.SBAddressRangeList()
108        self.assertEqual(range_list.GetSize(), 0)
109
110        range_list.Append(range1)
111        range_list.Append(range2)
112        range_list.Append(range3)
113        self.assertEqual(range_list.GetSize(), 3)
114        self.assertRaises(IndexError, lambda: range_list[3])
115
116        range1_copy = range_list.GetAddressRangeAtIndex(0)
117        self.assertEqual(range1.GetByteSize(), range1_copy.GetByteSize())
118        self.assertEqual(
119            range1.GetBaseAddress().GetOffset(),
120            range1_copy.GetBaseAddress().GetOffset(),
121        )
122
123        range2_copy = range_list.GetAddressRangeAtIndex(1)
124        self.assertEqual(range2.GetByteSize(), range2_copy.GetByteSize())
125        self.assertEqual(
126            range2.GetBaseAddress().GetOffset(),
127            range2_copy.GetBaseAddress().GetOffset(),
128        )
129
130        range3_copy = range_list.GetAddressRangeAtIndex(2)
131        self.assertEqual(range3.GetByteSize(), range3_copy.GetByteSize())
132        self.assertEqual(
133            range3.GetBaseAddress().GetOffset(),
134            range3_copy.GetBaseAddress().GetOffset(),
135        )
136
137        range_list.Clear()
138        self.assertEqual(range_list.GetSize(), 0)
139
140    def test_address_range_list_len(self):
141        """Make sure the len() operator works."""
142        range = lldb.SBAddressRange(self.addr1, 8)
143
144        range_list = lldb.SBAddressRangeList()
145        self.assertEqual(len(range_list), 0)
146
147        range_list.Append(range)
148        self.assertEqual(len(range_list), 1)
149
150    def test_address_range_list_iterator(self):
151        """Make sure the SBAddressRangeList iterator works."""
152        range1 = lldb.SBAddressRange(self.addr1, 8)
153        range2 = lldb.SBAddressRange(self.addr2, 16)
154        range3 = lldb.SBAddressRange(self.addr3, 32)
155
156        range_list = lldb.SBAddressRangeList()
157        range_list.Append(range1)
158        range_list.Append(range2)
159        range_list.Append(range3)
160        self.assertEqual(range_list.GetSize(), 3)
161
162        # Test the iterator
163        for range in range_list:
164            self.assertTrue(range.IsValid())
165
166    def test_address_range_print_invalid(self):
167        """Make sure the SBAddressRange can be printed when invalid."""
168        range = lldb.SBAddressRange()
169        self.assertEqual(str(range), "[0xffffffffffffffff-0xffffffffffffffff)")
170
171    def test_address_range_print_resolved(self):
172        """Make sure the SBAddressRange can be printed when resolved."""
173        lldb.target = self.target
174        error = lldb.SBError()
175        process = self.target.Launch(self.launch_info, error)
176        self.assertTrue(error.Success(), "Make sure process launched successfully")
177        self.assertTrue(process, PROCESS_IS_VALID)
178        self.assertState(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
179        script = (
180            "script "
181            + "bp = lldb.target.GetBreakpointAtIndex(0);"
182            + "loc = bp.GetLocationAtIndex(0);"
183            + "loc_addr = loc.GetAddress();"
184            + "func = loc_addr.GetFunction();"
185            + "range = func.GetRanges().GetAddressRangeAtIndex(0);"
186            + "print(range)"
187        )
188
189        interp = self.dbg.GetCommandInterpreter()
190        result = lldb.SBCommandReturnObject()
191        interp.HandleCommand(script, result, False)
192        self.assertTrue(result.Succeeded(), "script command succeeded")
193        # [0x1000-0x2000] // Resolved with target or addresses without sections
194        self.assertRegex(result.GetOutput(), "^\[0x[0-9a-f]+\-0x[0-9a-f]+\)")
195        process.Kill()
196
197    def test_address_range_print_no_section_resolved(self):
198        """Make sure the SBAddressRange can be printed with no secion."""
199        lldb.target = self.target
200        error = lldb.SBError()
201        process = self.target.Launch(self.launch_info, error)
202        self.assertTrue(error.Success(), "Make sure process launched successfully")
203        self.assertTrue(process, PROCESS_IS_VALID)
204        self.assertState(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
205
206        loc = self.bp1.GetLocationAtIndex(0)
207        loc_addr = loc.GetAddress()
208        func = loc_addr.GetFunction()
209        range = func.GetRanges().GetAddressRangeAtIndex(0)
210
211        addr = lldb.SBAddress()
212        addr.SetAddress(lldb.SBSection(), range.GetBaseAddress().GetOffset())
213        self.assertFalse(addr.GetSection().IsValid())
214        range = lldb.SBAddressRange(addr, range.GetByteSize())
215
216        range_str = str(range)
217        # [0x1000-0x2000] // Resolved with target or addresses without sections
218        self.assertRegex(range_str, "^\[0x[0-9a-f]+\-0x[0-9a-f]+\)$")
219        process.Kill()
220
221    def test_address_range_print_not_resolved(self):
222        """Make sure the SBAddressRange can be printed when not resolved."""
223        range = lldb.SBAddressRange(self.addr1, 8)
224        range_str = str(range)
225        # a.out[0x1000-0x2000] // Without target
226        self.assertRegex(range_str, "^a.out\[0x[0-9a-f]+\-0x[0-9a-f]+\)$")
227
228    def test_address_range_list_print(self):
229        """Make sure the SBAddressRangeList can be printed."""
230        range1 = lldb.SBAddressRange(self.addr1, 8)
231        range2 = lldb.SBAddressRange(self.addr2, 16)
232        range3 = lldb.SBAddressRange(self.addr3, 32)
233        self.dbg.SetAsync(True)
234
235        range_list = lldb.SBAddressRangeList()
236        self.assertEqual(range_list.GetSize(), 0)
237
238        range_list.Append(range1)
239        range_list.Append(range2)
240        range_list.Append(range3)
241        self.assertEqual(range_list.GetSize(), 3)
242
243        range_list_str = str(range_list)
244        self.assertTrue(range_list_str.startswith("["))
245        self.assertGreater(range_list_str.count(","), 1)
246        self.assertTrue(range_list_str.endswith("]"))
247
248    def test_address_range_list_indexing(self):
249        """Make sure the SBAddressRangeList can be printed."""
250        range1 = lldb.SBAddressRange(self.addr1, 8)
251        range2 = lldb.SBAddressRange(self.addr2, 16)
252        range_list = lldb.SBAddressRangeList()
253        range_list.Append(range1)
254        range_list.Append(range2)
255
256        self.assertEqual(range_list.GetSize(), 2)
257        self.assertRaises(IndexError, lambda: range_list[2])
258        self.assertRaises(TypeError, lambda: range_list["0"])
259        self.assertEqual(range_list[0], range1)
260        self.assertEqual(range_list[1], range2)
261        self.assertEqual(range_list[-1], range2)
262        self.assertEqual(range_list[-2], range1)
263