1f66a5e22SPavel Labathimport lldb 2f66a5e22SPavel Labathfrom lldbsuite.test.decorators import * 3f66a5e22SPavel Labathfrom lldbsuite.test.lldbtest import * 4f66a5e22SPavel Labathfrom lldbsuite.test import lldbutil 5f66a5e22SPavel Labath 6f66a5e22SPavel Labath 7f66a5e22SPavel Labathclass TestStepUntilAPI(TestBase): 8f66a5e22SPavel Labath NO_DEBUG_INFO_TESTCASE = True 9f66a5e22SPavel Labath 10f66a5e22SPavel Labath def setUp(self): 11f66a5e22SPavel Labath super().setUp() 12f66a5e22SPavel Labath 13f66a5e22SPavel Labath self.main_source = "main.c" 14f66a5e22SPavel Labath self.main_spec = lldb.SBFileSpec(self.main_source) 15f66a5e22SPavel Labath self.less_than_two = line_number("main.c", "Less than 2") 16f66a5e22SPavel Labath self.greater_than_two = line_number("main.c", "Greater than or equal to 2.") 17f66a5e22SPavel Labath self.back_out_in_main = line_number("main.c", "Back out in main") 18f66a5e22SPavel Labath self.in_foo = line_number("main.c", "In foo") 19f66a5e22SPavel Labath 20f66a5e22SPavel Labath def _build_dict_for_discontinuity(self): 21f66a5e22SPavel Labath return dict( 22f66a5e22SPavel Labath CFLAGS_EXTRAS="-funique-basic-block-section-names " 23f66a5e22SPavel Labath + "-ffunction-sections -fbasic-block-sections=list=" 24f66a5e22SPavel Labath + self.getSourcePath("function.list"), 25f66a5e22SPavel Labath LD_EXTRAS="-Wl,--script=" + self.getSourcePath("symbol.order"), 26f66a5e22SPavel Labath ) 27f66a5e22SPavel Labath 28f66a5e22SPavel Labath def _do_until(self, build_dict, args, until_line, expected_line): 29f66a5e22SPavel Labath self.build(dictionary=build_dict) 30f66a5e22SPavel Labath launch_info = lldb.SBLaunchInfo(args) 31f66a5e22SPavel Labath _, _, thread, _ = lldbutil.run_to_source_breakpoint( 32f66a5e22SPavel Labath self, "At the start", self.main_spec, launch_info 33f66a5e22SPavel Labath ) 34f66a5e22SPavel Labath 35f66a5e22SPavel Labath self.assertSuccess( 36f66a5e22SPavel Labath thread.StepOverUntil(self.frame(), self.main_spec, until_line) 37f66a5e22SPavel Labath ) 38f66a5e22SPavel Labath 39f66a5e22SPavel Labath self.runCmd("process status") 40f66a5e22SPavel Labath 41f66a5e22SPavel Labath line = self.frame().GetLineEntry().GetLine() 42f66a5e22SPavel Labath self.assertEqual( 43f66a5e22SPavel Labath line, expected_line, "Did not get the expected stop line number" 44f66a5e22SPavel Labath ) 45f66a5e22SPavel Labath 46f66a5e22SPavel Labath def _assertDiscontinuity(self): 47f66a5e22SPavel Labath target = self.target() 48f66a5e22SPavel Labath foo = target.FindFunctions("foo") 49f66a5e22SPavel Labath self.assertEqual(len(foo), 1) 50f66a5e22SPavel Labath foo = foo[0] 51f66a5e22SPavel Labath 52f66a5e22SPavel Labath call_me = self.target().FindFunctions("call_me") 53f66a5e22SPavel Labath self.assertEqual(len(call_me), 1) 54f66a5e22SPavel Labath call_me = call_me[0] 55f66a5e22SPavel Labath 56f66a5e22SPavel Labath foo_addr = foo.function.GetStartAddress().GetLoadAddress(target) 57f66a5e22SPavel Labath found_before = False 58f66a5e22SPavel Labath found_after = False 59f66a5e22SPavel Labath for range in call_me.function.GetRanges(): 60f66a5e22SPavel Labath addr = range.GetBaseAddress().GetLoadAddress(target) 61f66a5e22SPavel Labath if addr < foo_addr: 62f66a5e22SPavel Labath found_before = True 63f66a5e22SPavel Labath if addr > foo_addr: 64f66a5e22SPavel Labath found_after = True 65f66a5e22SPavel Labath 66f66a5e22SPavel Labath self.assertTrue( 67f66a5e22SPavel Labath found_before and found_after, 68f66a5e22SPavel Labath "'foo' is not between 'call_me'" + str(foo) + str(call_me), 69f66a5e22SPavel Labath ) 70f66a5e22SPavel Labath 71f66a5e22SPavel Labath def test_hitting(self): 72f66a5e22SPavel Labath """Test SBThread.StepOverUntil - targeting a line and hitting it.""" 73f66a5e22SPavel Labath self._do_until(None, None, self.less_than_two, self.less_than_two) 74f66a5e22SPavel Labath 75f66a5e22SPavel Labath @skipIf(oslist=lldbplatformutil.getDarwinOSTriples() + ["windows"]) 76*58fc8029SPavel Labath @skipIf(archs=no_match(["x86_64", "aarch64"])) 77f66a5e22SPavel Labath def test_hitting_discontinuous(self): 78f66a5e22SPavel Labath """Test SBThread.StepOverUntil - targeting a line and hitting it -- with 79f66a5e22SPavel Labath discontinuous functions""" 80f66a5e22SPavel Labath self._do_until( 81f66a5e22SPavel Labath self._build_dict_for_discontinuity(), 82f66a5e22SPavel Labath None, 83f66a5e22SPavel Labath self.less_than_two, 84f66a5e22SPavel Labath self.less_than_two, 85f66a5e22SPavel Labath ) 86f66a5e22SPavel Labath self._assertDiscontinuity() 87f66a5e22SPavel Labath 88f66a5e22SPavel Labath def test_missing(self): 89f66a5e22SPavel Labath """Test SBThread.StepOverUntil - targeting a line and missing it by stepping out to call site""" 90f66a5e22SPavel Labath self._do_until( 91f66a5e22SPavel Labath None, ["foo", "bar", "baz"], self.less_than_two, self.back_out_in_main 92f66a5e22SPavel Labath ) 93f66a5e22SPavel Labath 94f66a5e22SPavel Labath @skipIf(oslist=lldbplatformutil.getDarwinOSTriples() + ["windows"]) 95*58fc8029SPavel Labath @skipIf(archs=no_match(["x86_64", "aarch64"])) 96f66a5e22SPavel Labath def test_missing_discontinuous(self): 97f66a5e22SPavel Labath """Test SBThread.StepOverUntil - targeting a line and missing it by 98f66a5e22SPavel Labath stepping out to call site -- with discontinuous functions""" 99f66a5e22SPavel Labath self._do_until( 100f66a5e22SPavel Labath self._build_dict_for_discontinuity(), 101f66a5e22SPavel Labath ["foo", "bar", "baz"], 102f66a5e22SPavel Labath self.less_than_two, 103f66a5e22SPavel Labath self.back_out_in_main, 104f66a5e22SPavel Labath ) 105f66a5e22SPavel Labath self._assertDiscontinuity() 106f66a5e22SPavel Labath 107f66a5e22SPavel Labath def test_bad_line(self): 108f66a5e22SPavel Labath """Test that we get an error if attempting to step outside the current 109f66a5e22SPavel Labath function""" 110f66a5e22SPavel Labath self.build() 111f66a5e22SPavel Labath _, _, thread, _ = lldbutil.run_to_source_breakpoint( 112f66a5e22SPavel Labath self, "At the start", self.main_spec 113f66a5e22SPavel Labath ) 114f66a5e22SPavel Labath self.assertIn( 115f66a5e22SPavel Labath "step until target not in current function", 116f66a5e22SPavel Labath thread.StepOverUntil( 117f66a5e22SPavel Labath self.frame(), self.main_spec, self.in_foo 118f66a5e22SPavel Labath ).GetCString(), 119f66a5e22SPavel Labath ) 120f66a5e22SPavel Labath 121f66a5e22SPavel Labath @skipIf(oslist=lldbplatformutil.getDarwinOSTriples() + ["windows"]) 122*58fc8029SPavel Labath @skipIf(archs=no_match(["x86_64", "aarch64"])) 123f66a5e22SPavel Labath def test_bad_line_discontinuous(self): 124f66a5e22SPavel Labath """Test that we get an error if attempting to step outside the current 125f66a5e22SPavel Labath function -- and the function is discontinuous""" 126f66a5e22SPavel Labath self.build(dictionary=self._build_dict_for_discontinuity()) 127f66a5e22SPavel Labath _, _, thread, _ = lldbutil.run_to_source_breakpoint( 128f66a5e22SPavel Labath self, "At the start", self.main_spec 129f66a5e22SPavel Labath ) 130f66a5e22SPavel Labath self.assertIn( 131f66a5e22SPavel Labath "step until target not in current function", 132f66a5e22SPavel Labath thread.StepOverUntil( 133f66a5e22SPavel Labath self.frame(), self.main_spec, self.in_foo 134f66a5e22SPavel Labath ).GetCString(), 135f66a5e22SPavel Labath ) 136f66a5e22SPavel Labath self._assertDiscontinuity() 137