xref: /llvm-project/lldb/test/API/functionalities/thread/jump/TestThreadJump.py (revision 2238dcc39358353cac21df75c3c3286ab20b8f53)
1"""
2Test jumping to different places.
3"""
4
5
6import lldb
7from lldbsuite.test.decorators import *
8from lldbsuite.test.lldbtest import *
9from lldbsuite.test import lldbutil
10
11
12class ThreadJumpTestCase(TestBase):
13    def test(self):
14        """Test thread jump handling."""
15        self.build()
16        exe = self.getBuildArtifact("a.out")
17        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
18
19        # Find the line numbers for our breakpoints.
20        self.mark1 = line_number("main.cpp", "// 1st marker")
21        self.mark2 = line_number("main.cpp", "// 2nd marker")
22        self.mark3 = line_number("main.cpp", "// 3rd marker")
23        self.mark4 = line_number("main.cpp", "// 4th marker")
24        self.mark5 = line_number("other.cpp", "// other marker")
25
26        lldbutil.run_break_set_by_file_and_line(
27            self, "main.cpp", self.mark3, num_expected_locations=1
28        )
29        self.runCmd("run", RUN_SUCCEEDED)
30
31        # The stop reason of the thread should be breakpoint 1.
32        self.expect(
33            "thread list",
34            STOPPED_DUE_TO_BREAKPOINT + " 1",
35            substrs=[
36                "stopped",
37                "main.cpp:{}".format(self.mark3),
38                "stop reason = breakpoint 1",
39            ],
40        )
41
42        # Try the int path, force it to return 'a'
43        self.do_min_test(self.mark3, self.mark1, "i", "4")
44        # Try the int path, force it to return 'b'
45        self.do_min_test(self.mark3, self.mark2, "i", "5")
46        # Try the double path, force it to return 'a'
47        self.do_min_test(self.mark4, self.mark1, "j", "7")
48        # Expected to fail on powerpc64le architecture
49        if not self.isPPC64le():
50            # Try the double path, force it to return 'b'
51            self.do_min_test(self.mark4, self.mark2, "j", "8")
52
53        # Try jumping to another function in a different file.
54        self.runCmd("thread jump --file other.cpp --line %i --force" % self.mark5)
55        self.expect("process status", substrs=["at other.cpp:%i" % self.mark5])
56
57        # Try jumping to another function (without forcing)
58        self.expect(
59            "j main.cpp:%i" % self.mark1,
60            COMMAND_FAILED_AS_EXPECTED,
61            error=True,
62            substrs=["error"],
63        )
64
65    def do_min_test(self, start, jump, var, value):
66        # jump to the start marker
67        self.runCmd("j %i" % start)
68        self.runCmd("thread step-in")  # step into the min fn
69        # jump to the branch we're interested in
70        self.runCmd("j %i" % jump)
71        self.runCmd("thread step-out")  # return out
72        self.runCmd("thread step-over")  # assign to the global
73        self.expect("expr %s" % var, substrs=[value])  # check it
74