1 """Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms."""
5 from lldbsuite
.test
.decorators
import *
6 from lldbsuite
.test
.lldbtest
import *
7 from lldbsuite
.test
import lldbutil
10 class TestCStepping(TestBase
):
12 # Call super's setUp().
14 # Find the line numbers that we will step to in main:
15 self
.main_source
= "main.c"
17 @add_test_categories(["pyapi", "basic_process"])
18 @expectedFailureAll(oslist
=["freebsd"], bugnumber
="llvm.org/pr17932")
19 @expectedFailureAll(oslist
=["linux"], archs
=no_match(["i386", "x86_64"]))
20 @expectedFailureAll(oslist
=["windows"], bugnumber
="llvm.org/pr24777")
21 @expectedFailureNetBSD
22 def test_and_python_api(self
):
23 """Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms."""
25 exe
= self
.getBuildArtifact("a.out")
27 target
= self
.dbg
.CreateTarget(exe
)
28 self
.assertTrue(target
, VALID_TARGET
)
30 self
.main_source_spec
= lldb
.SBFileSpec(self
.main_source
)
32 breakpoints_to_disable
= []
34 break_1_in_main
= target
.BreakpointCreateBySourceRegex(
35 "// frame select 2, thread step-out while stopped at .c.1..",
36 self
.main_source_spec
,
38 self
.assertTrue(break_1_in_main
, VALID_BREAKPOINT
)
39 breakpoints_to_disable
.append(break_1_in_main
)
41 break_in_a
= target
.BreakpointCreateBySourceRegex(
42 "// break here to stop in a before calling b", self
.main_source_spec
44 self
.assertTrue(break_in_a
, VALID_BREAKPOINT
)
45 breakpoints_to_disable
.append(break_in_a
)
47 break_in_b
= target
.BreakpointCreateBySourceRegex(
48 "// thread step-out while stopped at .c.2..", self
.main_source_spec
50 self
.assertTrue(break_in_b
, VALID_BREAKPOINT
)
51 breakpoints_to_disable
.append(break_in_b
)
53 break_in_c
= target
.BreakpointCreateBySourceRegex(
54 "// Find the line number of function .c. here.", self
.main_source_spec
56 self
.assertTrue(break_in_c
, VALID_BREAKPOINT
)
57 breakpoints_to_disable
.append(break_in_c
)
59 # Now launch the process, and do not stop at entry point.
60 process
= target
.LaunchSimple(None, None, self
.get_process_working_directory())
62 self
.assertTrue(process
, PROCESS_IS_VALID
)
64 # The stop reason of the thread should be breakpoint.
65 threads
= lldbutil
.get_threads_stopped_at_breakpoint(process
, break_1_in_main
)
68 self
.fail("Failed to stop at first breakpoint in main.")
72 # Get the stop id and for fun make sure it increases:
73 old_stop_id
= process
.GetStopID()
75 # Now step over, which should cause us to hit the breakpoint in "a"
78 # The stop reason of the thread should be breakpoint.
79 threads
= lldbutil
.get_threads_stopped_at_breakpoint(process
, break_in_a
)
81 self
.fail("Failed to stop at breakpoint in a.")
83 # Check that the stop ID increases:
84 new_stop_id
= process
.GetStopID()
85 self
.assertGreater(new_stop_id
, old_stop_id
, "Stop ID increases monotonically.")
89 # Step over, and we should hit the breakpoint in b:
92 threads
= lldbutil
.get_threads_stopped_at_breakpoint(process
, break_in_b
)
94 self
.fail("Failed to stop at breakpoint in b.")
97 # Now try running some function, and make sure that we still end up in the same place
98 # and with the same stop reason.
99 frame
= thread
.GetFrameAtIndex(0)
100 current_line
= frame
.GetLineEntry().GetLine()
101 current_file
= frame
.GetLineEntry().GetFileSpec()
102 current_bp
= thread
.stop_reason_data
104 stop_id_before_expression
= process
.GetStopID()
105 stop_id_before_including_expressions
= process
.GetStopID(True)
107 frame
.EvaluateExpression("(int) printf (print_string)")
109 frame
= thread
.GetFrameAtIndex(0)
112 frame
.GetLineEntry().GetLine(),
113 "The line stayed the same after expression.",
117 frame
.GetLineEntry().GetFileSpec(),
118 "The file stayed the same after expression.",
121 thread
.GetStopReason(),
122 lldb
.eStopReasonBreakpoint
,
123 "We still say we stopped for a breakpoint.",
126 thread
.stop_reason_data
,
128 "And it is the same breakpoint.",
131 # Also make sure running the expression didn't change the public stop id
132 # but did change if we are asking for expression stops as well.
133 stop_id_after_expression
= process
.GetStopID()
134 stop_id_after_including_expressions
= process
.GetStopID(True)
137 stop_id_before_expression
,
138 stop_id_after_expression
,
139 "Expression calling doesn't change stop ID",
143 stop_id_after_including_expressions
,
144 stop_id_before_including_expressions
,
145 "Stop ID including expressions increments over expression call.",
148 # Do the same thing with an expression that's going to crash, and make
149 # sure we are still unchanged.
151 frame
.EvaluateExpression("((char *) 0)[0] = 'a'")
153 frame
= thread
.GetFrameAtIndex(0)
156 frame
.GetLineEntry().GetLine(),
157 "The line stayed the same after expression.",
161 frame
.GetLineEntry().GetFileSpec(),
162 "The file stayed the same after expression.",
165 thread
.GetStopReason(),
166 lldb
.eStopReasonBreakpoint
,
167 "We still say we stopped for a breakpoint.",
170 thread
.GetStopReasonDataAtIndex(0) == current_bp
[0]
171 and thread
.GetStopReasonDataAtIndex(1) == current_bp
[1],
172 "And it is the same breakpoint.",
175 # Now continue and make sure we just complete the step:
176 # Disable all our breakpoints first - sometimes the compiler puts two line table entries in for the
177 # breakpoint a "b" and we don't want to hit that.
178 for bkpt
in breakpoints_to_disable
:
179 bkpt
.SetEnabled(False)
183 self
.assertEqual(thread
.GetFrameAtIndex(0).GetFunctionName(), "a")
184 self
.assertStopReason(thread
.GetStopReason(), lldb
.eStopReasonPlanComplete
)
186 # And one more time should get us back to main:
189 self
.assertEqual(thread
.GetFrameAtIndex(0).GetFunctionName(), "main")
190 self
.assertStopReason(thread
.GetStopReason(), lldb
.eStopReasonPlanComplete
)
192 # Now make sure we can call a function, break in the called function,
193 # then have "continue" get us back out again:
194 frame
= thread
.GetFrameAtIndex(0)
195 frame
= thread
.GetFrameAtIndex(0)
196 current_line
= frame
.GetLineEntry().GetLine()
197 current_file
= frame
.GetLineEntry().GetFileSpec()
199 break_in_b
.SetEnabled(True)
200 options
= lldb
.SBExpressionOptions()
201 options
.SetIgnoreBreakpoints(False)
202 options
.SetFetchDynamicValue(False)
203 options
.SetUnwindOnError(False)
204 frame
.EvaluateExpression("b (4)", options
)
206 threads
= lldbutil
.get_threads_stopped_at_breakpoint(process
, break_in_b
)
208 if len(threads
) != 1:
209 self
.fail("Failed to stop at breakpoint in b when calling b.")
212 # So do a step over here to make sure we can still do that:
216 # See that we are still in b:
217 func_name
= thread
.GetFrameAtIndex(0).GetFunctionName()
218 self
.assertEqual(func_name
, "b", "Should be in 'b', were in %s" % (func_name
))
220 # Okay, now if we continue, we will finish off our function call and we
221 # should end up back in "a" as if nothing had happened:
225 thread
.GetFrameAtIndex(0).GetLineEntry().GetLine(), current_line
228 thread
.GetFrameAtIndex(0).GetLineEntry().GetFileSpec(), current_file
231 # Now we are going to test step in targeting a function:
233 break_in_b
.SetEnabled(False)
235 break_before_complex_1
= target
.BreakpointCreateBySourceRegex(
236 "// Stop here to try step in targeting b.", self
.main_source_spec
238 self
.assertTrue(break_before_complex_1
, VALID_BREAKPOINT
)
240 break_before_complex_2
= target
.BreakpointCreateBySourceRegex(
241 "// Stop here to try step in targeting complex.", self
.main_source_spec
243 self
.assertTrue(break_before_complex_2
, VALID_BREAKPOINT
)
245 break_before_complex_3
= target
.BreakpointCreateBySourceRegex(
246 "// Stop here to step targeting b and hitting breakpoint.",
247 self
.main_source_spec
,
249 self
.assertTrue(break_before_complex_3
, VALID_BREAKPOINT
)
251 break_before_complex_4
= target
.BreakpointCreateBySourceRegex(
252 "// Stop here to make sure bogus target steps over.", self
.main_source_spec
254 self
.assertTrue(break_before_complex_4
, VALID_BREAKPOINT
)
256 threads
= lldbutil
.continue_to_breakpoint(process
, break_before_complex_1
)
257 self
.assertEqual(len(threads
), 1)
259 break_before_complex_1
.SetEnabled(False)
262 self
.assertEqual(thread
.GetFrameAtIndex(0).GetFunctionName(), "b")
264 # Now continue out and stop at the next call to complex. This time
265 # step all the way into complex:
266 threads
= lldbutil
.continue_to_breakpoint(process
, break_before_complex_2
)
267 self
.assertEqual(len(threads
), 1)
269 break_before_complex_2
.SetEnabled(False)
271 thread
.StepInto("complex")
272 self
.assertEqual(thread
.GetFrameAtIndex(0).GetFunctionName(), "complex")
274 # Now continue out and stop at the next call to complex. This time
275 # enable breakpoints in a and c and then step targeting b:
276 threads
= lldbutil
.continue_to_breakpoint(process
, break_before_complex_3
)
277 self
.assertEqual(len(threads
), 1)
279 break_before_complex_3
.SetEnabled(False)
281 break_at_start_of_a
= target
.BreakpointCreateByName("a")
282 break_at_start_of_c
= target
.BreakpointCreateByName("c")
285 threads
= lldbutil
.get_stopped_threads(process
, lldb
.eStopReasonBreakpoint
)
287 self
.assertEqual(len(threads
), 1)
289 stop_break_id
= thread
.GetStopReasonDataAtIndex(0)
291 stop_break_id
== break_at_start_of_a
.GetID()
292 or stop_break_id
== break_at_start_of_c
.GetID()
295 break_at_start_of_a
.SetEnabled(False)
296 break_at_start_of_c
.SetEnabled(False)
299 self
.assertEqual(thread
.GetFrameAtIndex(0).GetFunctionName(), "b")
301 # Now continue out and stop at the next call to complex. This time
302 # enable breakpoints in a and c and then step targeting b:
303 threads
= lldbutil
.continue_to_breakpoint(process
, break_before_complex_4
)
304 self
.assertEqual(len(threads
), 1)
306 break_before_complex_4
.SetEnabled(False)
308 thread
.StepInto("NoSuchFunction")
309 self
.assertEqual(thread
.GetFrameAtIndex(0).GetFunctionName(), "main")