xref: /llvm-project/lldb/test/API/functionalities/thread/step_until/TestStepUntilAPI.py (revision 58fc8029e91bf56811444d4a37a8f517a43bdc11)
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