2 Test thread step-in, step-over and step-out work with the "Avoid no debug" option.
7 from lldbsuite
.test
.decorators
import *
8 from lldbsuite
.test
.lldbtest
import *
9 from lldbsuite
.test
import lldbutil
12 class StepAvoidsNoDebugTestCase(TestBase
):
13 @add_test_categories(["pyapi"])
15 archs
=["aarch64"], oslist
=["windows"], bugnumber
="llvm.org/pr56292"
17 def test_step_out_with_python(self
):
18 """Test stepping out using avoid-no-debug with dsyms."""
20 self
.get_to_starting_point()
21 self
.do_step_out_past_nodebug()
23 @add_test_categories(["pyapi"])
24 @decorators.expectedFailureAll(compiler
="gcc", bugnumber
="llvm.org/pr28549")
25 @decorators.expectedFailureAll(
27 compiler_version
=[">=", "3.9"],
29 oslist
=no_match(["freebsd"]),
30 bugnumber
="llvm.org/pr28549",
33 archs
=["aarch64"], oslist
=["windows"], bugnumber
="llvm.org/pr56292"
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(compiler
="gcc", bugnumber
="llvm.org/pr28549")
43 @decorators.expectedFailureAll(
45 compiler_version
=[">=", "3.9"],
47 oslist
=no_match(["freebsd"]),
48 bugnumber
="llvm.org/pr28549",
51 archs
=["aarch64"], oslist
=["windows"], bugnumber
="llvm.org/pr56292"
53 def test_step_in_with_python(self
):
54 """Test stepping in using avoid-no-debug with dwarf."""
56 self
.get_to_starting_point()
57 self
.do_step_in_past_nodebug()
61 self
.main_source
= "with-debug.c"
62 self
.main_source_spec
= lldb
.SBFileSpec("with-debug.c")
63 self
.dbg
.HandleCommand(
64 "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"
71 TestBase
.tearDown(self
)
73 def hit_correct_line(self
, pattern
):
74 target_line
= line_number(self
.main_source
, pattern
)
75 self
.assertNotEqual(target_line
, 0, "Could not find source pattern " + pattern
)
76 cur_line
= self
.thread
.frames
[0].GetLineEntry().GetLine()
80 "Stepped to line %d instead of expected %d with pattern '%s'."
81 % (cur_line
, target_line
, pattern
),
84 def hit_correct_function(self
, pattern
):
85 name
= self
.thread
.frames
[0].GetFunctionName()
88 "Got to '%s' not the expected function '%s'." % (name
, pattern
),
91 def get_to_starting_point(self
):
92 exe
= self
.getBuildArtifact("a.out")
93 error
= lldb
.SBError()
95 self
.target
= self
.dbg
.CreateTarget(exe
)
96 self
.assertTrue(self
.target
, VALID_TARGET
)
98 inner_bkpt
= self
.target
.BreakpointCreateBySourceRegex(
99 "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()
108 self
.assertTrue(self
.process
, PROCESS_IS_VALID
)
110 # Now finish, and make sure the return value is correct.
111 threads
= lldbutil
.get_threads_stopped_at_breakpoint(self
.process
, inner_bkpt
)
112 self
.assertEquals(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)"
123 self
.thread
.StepOut()
124 self
.hit_correct_line(
125 "int return_value = no_debug_caller(5, called_from_nodebug)"
128 def do_step_over_past_nodebug(self
):
129 self
.thread
.StepOver()
130 self
.hit_correct_line(
131 "intermediate_return_value = called_from_nodebug_actual(some_value)"
133 self
.thread
.StepOver()
134 self
.hit_correct_line("return intermediate_return_value")
135 self
.thread
.StepOver()
136 # Note, lldb doesn't follow gdb's distinction between "step-out" and "step-over/step-in"
137 # when exiting a frame. In all cases we leave the pc at the point where we exited the
138 # frame. In gdb, step-over/step-in move to the end of the line they stepped out to.
139 # If we ever change this we will need to fix this test.
140 self
.hit_correct_line(
141 "int return_value = no_debug_caller(5, called_from_nodebug)"
144 def do_step_in_past_nodebug(self
):
145 self
.thread
.StepInto()
146 self
.hit_correct_line(
147 "intermediate_return_value = called_from_nodebug_actual(some_value)"
149 self
.thread
.StepInto()
150 self
.hit_correct_line("return intermediate_return_value")
151 self
.thread
.StepInto()
152 # Note, lldb doesn't follow gdb's distinction between "step-out" and "step-over/step-in"
153 # when exiting a frame. In all cases we leave the pc at the point where we exited the
154 # frame. In gdb, step-over/step-in move to the end of the line they stepped out to.
155 # If we ever change this we will need to fix this test.
156 self
.hit_correct_line(
157 "int return_value = no_debug_caller(5, called_from_nodebug)"