1"""Test that lldb picks the correct DWARF location list entry with a return-pc out of bounds.""" 2 3import lldb 4from lldbsuite.test.decorators import * 5from lldbsuite.test.lldbtest import * 6from lldbsuite.test import lldbutil 7 8 9class LocationListLookupTestCase(TestBase): 10 def launch(self) -> lldb.SBProcess: 11 exe = self.getBuildArtifact("a.out") 12 target = self.dbg.CreateTarget(exe) 13 self.assertTrue(target, VALID_TARGET) 14 self.dbg.SetAsync(False) 15 16 li = lldb.SBLaunchInfo(["a.out"]) 17 error = lldb.SBError() 18 process = target.Launch(li, error) 19 self.assertTrue(process.IsValid()) 20 self.assertTrue(process.is_stopped) 21 22 return process 23 24 def check_local_vars(self, process: lldb.SBProcess, check_expr: bool): 25 # Find `bar` on the stack, then 26 # make sure we can read out the local 27 # variables (with both `frame var` and `expr`) 28 for f in process.selected_thread.frames: 29 frame_name = f.GetDisplayFunctionName() 30 if frame_name is not None and frame_name.startswith("Foo::bar"): 31 argv = f.GetValueForVariablePath("argv").GetChildAtIndex(0) 32 strm = lldb.SBStream() 33 argv.GetDescription(strm) 34 self.assertNotEqual(strm.GetData().find("a.out"), -1) 35 36 if check_expr: 37 process.selected_thread.selected_frame = f 38 self.expect_expr("this", result_type="Foo *") 39 40 @skipIf(oslist=["linux"], archs=["arm"]) 41 @skipIfDarwin 42 def test_loclist_frame_var(self): 43 self.build() 44 self.check_local_vars(self.launch(), check_expr=False) 45 46 @skipIf(dwarf_version=["<", "3"]) 47 @skipIf(compiler="clang", compiler_version=["<", "12.0"]) 48 @skipUnlessDarwin 49 def test_loclist_expr(self): 50 self.build() 51 self.check_local_vars(self.launch(), check_expr=True) 52