2 Test thread step-in, step-over and step-out work with the "Avoid no debug" option.
9 from lldbsuite.test.decorators import *
10 from lldbsuite.test.lldbtest import *
11 from lldbsuite.test import lldbutil
14 class StepAvoidsNoDebugTestCase(TestBase):
16 mydir = TestBase.compute_mydir(__file__)
18 @add_test_categories(['pyapi'])
19 def test_step_out_with_python(self):
20 """Test stepping out using avoid-no-debug with dsyms."""
22 self.get_to_starting_point()
23 self.do_step_out_past_nodebug()
25 @add_test_categories(['pyapi'])
26 @decorators.expectedFailureAll(
27 compiler="gcc", bugnumber="llvm.org/pr28549")
28 @decorators.expectedFailureAll(
34 bugnumber="llvm.org/pr28549")
35 def test_step_over_with_python(self):
36 """Test stepping over using avoid-no-debug with dwarf."""
38 self.get_to_starting_point()
39 self.do_step_over_past_nodebug()
41 @add_test_categories(['pyapi'])
42 @decorators.expectedFailureAll(
43 compiler="gcc", bugnumber="llvm.org/pr28549")
44 @decorators.expectedFailureAll(
50 bugnumber="llvm.org/pr28549")
51 @expectedFailureAll(oslist=["ios", "tvos", "bridgeos"], bugnumber="<rdar://problem/34026777>") # lldb doesn't step past last source line in function on arm64
52 @expectedFailureAll(archs=["aarch64"], oslist=["linux"],
53 bugnumber="llvm.org/pr44057")
54 def test_step_in_with_python(self):
55 """Test stepping in using avoid-no-debug with dwarf."""
57 self.get_to_starting_point()
58 self.do_step_in_past_nodebug()
62 self.main_source = "with-debug.c"
63 self.main_source_spec = lldb.SBFileSpec("with-debug.c")
64 self.dbg.HandleCommand(
65 "settings set target.process.thread.step-out-avoid-nodebug true")
68 self.dbg.HandleCommand(
69 "settings set target.process.thread.step-out-avoid-nodebug false")
70 TestBase.tearDown(self)
72 def hit_correct_line(self, pattern):
73 target_line = line_number(self.main_source, pattern)
76 "Could not find source pattern " +
78 cur_line = self.thread.frames[0].GetLineEntry().GetLine()
80 cur_line == target_line,
81 "Stepped to line %d instead of expected %d with pattern '%s'." %
86 def hit_correct_function(self, pattern):
87 name = self.thread.frames[0].GetFunctionName()
89 pattern in name, "Got to '%s' not the expected function '%s'." %
92 def get_to_starting_point(self):
93 exe = self.getBuildArtifact("a.out")
94 error = lldb.SBError()
96 self.target = self.dbg.CreateTarget(exe)
97 self.assertTrue(self.target, VALID_TARGET)
99 inner_bkpt = self.target.BreakpointCreateBySourceRegex(
100 "Stop here and step out of me", self.main_source_spec)
101 self.assertTrue(inner_bkpt, VALID_BREAKPOINT)
103 # Now launch the process, and do not stop at entry point.
104 self.process = self.target.LaunchSimple(
105 None, None, self.get_process_working_directory())
107 self.assertTrue(self.process, PROCESS_IS_VALID)
109 # Now finish, and make sure the return value is correct.
110 threads = lldbutil.get_threads_stopped_at_breakpoint(
111 self.process, inner_bkpt)
112 self.assertTrue(len(threads) == 1, "Stopped at inner breakpoint.")
113 self.thread = threads[0]
115 def do_step_out_past_nodebug(self):
116 # The first step out takes us to the called_from_nodebug frame, just to make sure setting
117 # step-out-avoid-nodebug doesn't change the behavior in frames with
119 self.thread.StepOut()
120 self.hit_correct_line(
121 "intermediate_return_value = called_from_nodebug_actual(some_value)")
122 self.thread.StepOut()
123 self.hit_correct_line(
124 "int return_value = no_debug_caller(5, called_from_nodebug)")
126 def do_step_over_past_nodebug(self):
127 self.thread.StepOver()
128 self.hit_correct_line(
129 "intermediate_return_value = called_from_nodebug_actual(some_value)")
130 self.thread.StepOver()
131 self.hit_correct_line("return intermediate_return_value")
132 self.thread.StepOver()
133 # Note, lldb doesn't follow gdb's distinction between "step-out" and "step-over/step-in"
134 # when exiting a frame. In all cases we leave the pc at the point where we exited the
135 # frame. In gdb, step-over/step-in move to the end of the line they stepped out to.
136 # If we ever change this we will need to fix this test.
137 self.hit_correct_line(
138 "int return_value = no_debug_caller(5, called_from_nodebug)")
140 def do_step_in_past_nodebug(self):
141 self.thread.StepInto()
142 self.hit_correct_line(
143 "intermediate_return_value = called_from_nodebug_actual(some_value)")
144 self.thread.StepInto()
145 self.hit_correct_line("return intermediate_return_value")
146 self.thread.StepInto()
147 # Note, lldb doesn't follow gdb's distinction between "step-out" and "step-over/step-in"
148 # when exiting a frame. In all cases we leave the pc at the point where we exited the
149 # frame. In gdb, step-over/step-in move to the end of the line they stepped out to.
150 # If we ever change this we will need to fix this test.
151 self.hit_correct_line(
152 "int return_value = no_debug_caller(5, called_from_nodebug)")