199451b44SJordan Rupprecht"""
299451b44SJordan RupprechtTest jumping to different places.
399451b44SJordan Rupprecht"""
499451b44SJordan Rupprecht
599451b44SJordan Rupprecht
699451b44SJordan Rupprecht
799451b44SJordan Rupprechtimport lldb
899451b44SJordan Rupprechtfrom lldbsuite.test.decorators import *
999451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import *
1099451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil
1199451b44SJordan Rupprecht
1299451b44SJordan Rupprecht
1399451b44SJordan Rupprechtclass ThreadJumpTestCase(TestBase):
1499451b44SJordan Rupprecht
1599451b44SJordan Rupprecht    def test(self):
1699451b44SJordan Rupprecht        """Test thread jump handling."""
17*d7dbe2c4SPavel Labath        self.build()
1899451b44SJordan Rupprecht        exe = self.getBuildArtifact("a.out")
1999451b44SJordan Rupprecht        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
2099451b44SJordan Rupprecht
2199451b44SJordan Rupprecht        # Find the line numbers for our breakpoints.
2299451b44SJordan Rupprecht        self.mark1 = line_number('main.cpp', '// 1st marker')
2399451b44SJordan Rupprecht        self.mark2 = line_number('main.cpp', '// 2nd marker')
2499451b44SJordan Rupprecht        self.mark3 = line_number('main.cpp', '// 3rd marker')
2599451b44SJordan Rupprecht        self.mark4 = line_number('main.cpp', '// 4th marker')
2699451b44SJordan Rupprecht        self.mark5 = line_number('other.cpp', '// other marker')
2799451b44SJordan Rupprecht
2899451b44SJordan Rupprecht        lldbutil.run_break_set_by_file_and_line(
2999451b44SJordan Rupprecht            self, "main.cpp", self.mark3, num_expected_locations=1)
3099451b44SJordan Rupprecht        self.runCmd("run", RUN_SUCCEEDED)
3199451b44SJordan Rupprecht
3299451b44SJordan Rupprecht        # The stop reason of the thread should be breakpoint 1.
3399451b44SJordan Rupprecht        self.expect(
3499451b44SJordan Rupprecht            "thread list",
3599451b44SJordan Rupprecht            STOPPED_DUE_TO_BREAKPOINT + " 1",
3699451b44SJordan Rupprecht            substrs=[
3799451b44SJordan Rupprecht                'stopped',
3899451b44SJordan Rupprecht                'main.cpp:{}'.format(
3999451b44SJordan Rupprecht                    self.mark3),
4099451b44SJordan Rupprecht                'stop reason = breakpoint 1'])
4199451b44SJordan Rupprecht
4299451b44SJordan Rupprecht        # Try the int path, force it to return 'a'
4399451b44SJordan Rupprecht        self.do_min_test(self.mark3, self.mark1, "i", "4")
4499451b44SJordan Rupprecht        # Try the int path, force it to return 'b'
4599451b44SJordan Rupprecht        self.do_min_test(self.mark3, self.mark2, "i", "5")
4699451b44SJordan Rupprecht        # Try the double path, force it to return 'a'
4799451b44SJordan Rupprecht        self.do_min_test(self.mark4, self.mark1, "j", "7")
4899451b44SJordan Rupprecht        # Expected to fail on powerpc64le architecture
4999451b44SJordan Rupprecht        if not self.isPPC64le():
5099451b44SJordan Rupprecht            # Try the double path, force it to return 'b'
5199451b44SJordan Rupprecht            self.do_min_test(self.mark4, self.mark2, "j", "8")
5299451b44SJordan Rupprecht
5399451b44SJordan Rupprecht        # Try jumping to another function in a different file.
5499451b44SJordan Rupprecht        self.runCmd(
5599451b44SJordan Rupprecht            "thread jump --file other.cpp --line %i --force" %
5699451b44SJordan Rupprecht            self.mark5)
5799451b44SJordan Rupprecht        self.expect("process status",
5899451b44SJordan Rupprecht                    substrs=["at other.cpp:%i" % self.mark5])
5999451b44SJordan Rupprecht
6099451b44SJordan Rupprecht        # Try jumping to another function (without forcing)
6199451b44SJordan Rupprecht        self.expect(
6299451b44SJordan Rupprecht            "j main.cpp:%i" %
6399451b44SJordan Rupprecht            self.mark1,
6499451b44SJordan Rupprecht            COMMAND_FAILED_AS_EXPECTED,
6599451b44SJordan Rupprecht            error=True,
6699451b44SJordan Rupprecht            substrs=["error"])
6799451b44SJordan Rupprecht
6899451b44SJordan Rupprecht    def do_min_test(self, start, jump, var, value):
6999451b44SJordan Rupprecht        # jump to the start marker
7099451b44SJordan Rupprecht        self.runCmd("j %i" % start)
7199451b44SJordan Rupprecht        self.runCmd("thread step-in")                   # step into the min fn
7299451b44SJordan Rupprecht        # jump to the branch we're interested in
7399451b44SJordan Rupprecht        self.runCmd("j %i" % jump)
7499451b44SJordan Rupprecht        self.runCmd("thread step-out")                  # return out
7599451b44SJordan Rupprecht        self.runCmd("thread step-over")                 # assign to the global
7699451b44SJordan Rupprecht        self.expect("expr %s" % var, substrs=[value])  # check it
77