143 lines · python
1"""2Test jumping to different places.3"""4 5 6import lldb7from lldbsuite.test.decorators import *8from lldbsuite.test.lldbtest import *9from lldbsuite.test import lldbutil10 11 12class ThreadJumpTestCase(TestBase):13 def setUp(self):14 TestBase.setUp(self)15 self.build()16 17 def test(self):18 """Test thread jump handling."""19 exe = self.getBuildArtifact("a.out")20 self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)21 22 # Find the line numbers for our breakpoints.23 self.mark1 = line_number("main.cpp", "// 1st marker")24 self.mark2 = line_number("main.cpp", "// 2nd marker")25 self.mark3 = line_number("main.cpp", "// 3rd marker")26 self.mark4 = line_number("main.cpp", "// 4th marker")27 self.mark5 = line_number("other.cpp", "// other marker")28 29 lldbutil.run_break_set_by_file_and_line(30 self, "main.cpp", self.mark3, num_expected_locations=131 )32 self.runCmd("run", RUN_SUCCEEDED)33 34 # The stop reason of the thread should be breakpoint 1.35 self.expect(36 "thread list",37 STOPPED_DUE_TO_BREAKPOINT + " 1",38 substrs=[39 "stopped",40 "main.cpp:{}".format(self.mark3),41 "stop reason = breakpoint 1",42 ],43 )44 45 # Try the int path, force it to return 'a'46 self.do_min_test(self.mark3, self.mark1, "i", "4")47 # Try the int path, force it to return 'b'48 self.do_min_test(self.mark3, self.mark2, "i", "5")49 # Try the double path, force it to return 'a'50 self.do_min_test(self.mark4, self.mark1, "j", "7")51 # Expected to fail on powerpc64le architecture52 if not self.isPPC64le():53 # Try the double path, force it to return 'b'54 self.do_min_test(self.mark4, self.mark2, "j", "8")55 56 # Try jumping to another function in a different file.57 self.runCmd("thread jump --file other.cpp --line %i --force" % self.mark5)58 self.expect("process status", substrs=["at other.cpp:%i" % self.mark5])59 60 # Try jumping to another function (without forcing)61 self.expect(62 "j main.cpp:%i" % self.mark1,63 COMMAND_FAILED_AS_EXPECTED,64 error=True,65 substrs=["error"],66 )67 68 @expectedFailureAll(compiler="clang", compiler_version=["<", "17.0"])69 def test_jump_offset(self):70 """Test Thread Jump by negative or positive offset"""71 exe = self.getBuildArtifact("a.out")72 file_name = "main.cpp"73 self.runCmd(f"target create {exe}", CURRENT_EXECUTABLE_SET)74 75 pos_jump = line_number(file_name, "// jump_offset 1")76 neg_jump = line_number(file_name, "// jump_offset 2")77 pos_breakpoint = line_number(file_name, "// breakpoint 1")78 neg_breakpoint = line_number(file_name, "// breakpoint 2")79 pos_jump_offset = pos_jump - pos_breakpoint80 neg_jump_offset = neg_jump - neg_breakpoint81 82 var_1, var_1_value = ("var_1", "10")83 var_2, var_2_value = ("var_2", "40")84 var_3, var_3_value = ("var_3", "10")85 86 # create pos_breakpoint and neg_breakpoint87 lldbutil.run_break_set_by_file_and_line(88 self, file_name, pos_breakpoint, num_expected_locations=189 )90 lldbutil.run_break_set_by_file_and_line(91 self, file_name, neg_breakpoint, num_expected_locations=192 )93 94 self.runCmd("run", RUN_SUCCEEDED)95 96 # test positive jump97 # The stop reason of the thread should be breakpoint 1.98 self.expect(99 "thread list",100 STOPPED_DUE_TO_BREAKPOINT + " 1",101 substrs=[102 "stopped",103 f"{file_name}:{pos_breakpoint}",104 "stop reason = breakpoint 1",105 ],106 )107 108 self.runCmd(f"thread jump --by +{pos_jump_offset}")109 self.expect("process status", substrs=[f"at {file_name}:{pos_jump}"])110 self.expect(f"print {var_1}", substrs=[var_1_value])111 112 self.runCmd("thread step-over")113 self.expect(f"print {var_2}", substrs=[var_2_value])114 115 self.runCmd("continue")116 117 # test negative jump118 # The stop reason of the thread should be breakpoint 1.119 self.expect(120 "thread list",121 STOPPED_DUE_TO_BREAKPOINT + " 2",122 substrs=[123 "stopped",124 f"{file_name}:{neg_breakpoint}",125 "stop reason = breakpoint 2",126 ],127 )128 129 self.runCmd(f"thread jump --by {neg_jump_offset}")130 self.expect("process status", substrs=[f"at {file_name}:{neg_jump}"])131 self.runCmd("thread step-over")132 self.expect(f"print {var_3}", substrs=[var_3_value])133 134 def do_min_test(self, start, jump, var, value):135 # jump to the start marker136 self.runCmd("j %i" % start)137 self.runCmd("thread step-in") # step into the min fn138 # jump to the branch we're interested in139 self.runCmd("j %i" % jump)140 self.runCmd("thread step-out") # return out141 self.runCmd("thread step-over") # assign to the global142 self.expect("expr %s" % var, substrs=[value]) # check it143