diff options
Diffstat (limited to 'packages/Python/lldbsuite/test/lang/c/stepping/TestStepAndBreakpoints.py')
-rw-r--r-- | packages/Python/lldbsuite/test/lang/c/stepping/TestStepAndBreakpoints.py | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/packages/Python/lldbsuite/test/lang/c/stepping/TestStepAndBreakpoints.py b/packages/Python/lldbsuite/test/lang/c/stepping/TestStepAndBreakpoints.py new file mode 100644 index 0000000..c7a3de4 --- /dev/null +++ b/packages/Python/lldbsuite/test/lang/c/stepping/TestStepAndBreakpoints.py @@ -0,0 +1,242 @@ +"""Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms.""" + +from __future__ import print_function + + + +import os, time +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * + +class TestCStepping(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def getCategories(self): + return ['basic_process'] + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line numbers that we will step to in main: + self.main_source = "main.c" + + @expectedFailureFreeBSD('llvm.org/pr17932') + @expectedFailureLinux # llvm.org/pr14437 + @expectedFailureWindows("llvm.org/pr24777") + @add_test_categories(['pyapi']) + def test_and_python_api(self): + """Test stepping over vrs. hitting breakpoints & subsequent stepping in various forms.""" + self.build() + exe = os.path.join(os.getcwd(), "a.out") + + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, VALID_TARGET) + + self.main_source_spec = lldb.SBFileSpec (self.main_source) + + breakpoints_to_disable = [] + + break_1_in_main = target.BreakpointCreateBySourceRegex ('// frame select 2, thread step-out while stopped at .c.1..', self.main_source_spec) + self.assertTrue(break_1_in_main, VALID_BREAKPOINT) + breakpoints_to_disable.append (break_1_in_main) + + break_in_a = target.BreakpointCreateBySourceRegex ('// break here to stop in a before calling b', self.main_source_spec) + self.assertTrue(break_in_a, VALID_BREAKPOINT) + breakpoints_to_disable.append (break_in_a) + + break_in_b = target.BreakpointCreateBySourceRegex ('// thread step-out while stopped at .c.2..', self.main_source_spec) + self.assertTrue(break_in_b, VALID_BREAKPOINT) + breakpoints_to_disable.append (break_in_b) + + break_in_c = target.BreakpointCreateBySourceRegex ('// Find the line number of function .c. here.', self.main_source_spec) + self.assertTrue(break_in_c, VALID_BREAKPOINT) + breakpoints_to_disable.append (break_in_c) + + # Now launch the process, and do not stop at entry point. + process = target.LaunchSimple (None, None, self.get_process_working_directory()) + + self.assertTrue(process, PROCESS_IS_VALID) + + # The stop reason of the thread should be breakpoint. + threads = lldbutil.get_threads_stopped_at_breakpoint (process, break_1_in_main) + + if len(threads) != 1: + self.fail ("Failed to stop at first breakpoint in main.") + + thread = threads[0] + + # Get the stop id and for fun make sure it increases: + old_stop_id = process.GetStopID() + + # Now step over, which should cause us to hit the breakpoint in "a" + thread.StepOver() + + # The stop reason of the thread should be breakpoint. + threads = lldbutil.get_threads_stopped_at_breakpoint (process, break_in_a) + if len(threads) != 1: + self.fail ("Failed to stop at breakpoint in a.") + + # Check that the stop ID increases: + new_stop_id = process.GetStopID() + self.assertTrue(new_stop_id > old_stop_id, "Stop ID increases monotonically.") + + thread = threads[0] + + # Step over, and we should hit the breakpoint in b: + thread.StepOver() + + threads = lldbutil.get_threads_stopped_at_breakpoint (process, break_in_b) + if len(threads) != 1: + self.fail ("Failed to stop at breakpoint in b.") + thread = threads[0] + + # Now try running some function, and make sure that we still end up in the same place + # and with the same stop reason. + frame = thread.GetFrameAtIndex(0) + current_line = frame.GetLineEntry().GetLine() + current_file = frame.GetLineEntry().GetFileSpec() + current_bp = [] + current_bp.append(thread.GetStopReasonDataAtIndex(0)) + current_bp.append(thread.GetStopReasonDataAtIndex(1)) + + stop_id_before_expression = process.GetStopID() + stop_id_before_including_expressions = process.GetStopID(True) + + frame.EvaluateExpression ("(int) printf (print_string)") + + frame = thread.GetFrameAtIndex(0) + self.assertTrue (current_line == frame.GetLineEntry().GetLine(), "The line stayed the same after expression.") + self.assertTrue (current_file == frame.GetLineEntry().GetFileSpec(), "The file stayed the same after expression.") + self.assertTrue (thread.GetStopReason() == lldb.eStopReasonBreakpoint, "We still say we stopped for a breakpoint.") + self.assertTrue (thread.GetStopReasonDataAtIndex(0) == current_bp[0] and thread.GetStopReasonDataAtIndex(1) == current_bp[1], "And it is the same breakpoint.") + + # Also make sure running the expression didn't change the public stop id + # but did change if we are asking for expression stops as well. + stop_id_after_expression = process.GetStopID() + stop_id_after_including_expressions = process.GetStopID(True) + + self.assertTrue (stop_id_before_expression == stop_id_after_expression, "Expression calling doesn't change stop ID") + + self.assertTrue (stop_id_after_including_expressions > stop_id_before_including_expressions, "Stop ID including expressions increments over expression call.") + + # Do the same thing with an expression that's going to crash, and make sure we are still unchanged. + + frame.EvaluateExpression ("((char *) 0)[0] = 'a'") + + frame = thread.GetFrameAtIndex(0) + self.assertTrue (current_line == frame.GetLineEntry().GetLine(), "The line stayed the same after expression.") + self.assertTrue (current_file == frame.GetLineEntry().GetFileSpec(), "The file stayed the same after expression.") + self.assertTrue (thread.GetStopReason() == lldb.eStopReasonBreakpoint, "We still say we stopped for a breakpoint.") + self.assertTrue (thread.GetStopReasonDataAtIndex(0) == current_bp[0] and thread.GetStopReasonDataAtIndex(1) == current_bp[1], "And it is the same breakpoint.") + + # Now continue and make sure we just complete the step: + # Disable all our breakpoints first - sometimes the compiler puts two line table entries in for the + # breakpoint a "b" and we don't want to hit that. + for bkpt in breakpoints_to_disable: + bkpt.SetEnabled(False) + + process.Continue() + + self.assertTrue (thread.GetFrameAtIndex(0).GetFunctionName() == "a") + self.assertTrue (thread.GetStopReason() == lldb.eStopReasonPlanComplete) + + # And one more time should get us back to main: + process.Continue() + + self.assertTrue (thread.GetFrameAtIndex(0).GetFunctionName() == "main") + self.assertTrue (thread.GetStopReason() == lldb.eStopReasonPlanComplete) + + # Now make sure we can call a function, break in the called function, then have "continue" get us back out again: + frame = thread.GetFrameAtIndex(0) + frame = thread.GetFrameAtIndex(0) + current_line = frame.GetLineEntry().GetLine() + current_file = frame.GetLineEntry().GetFileSpec() + + break_in_b.SetEnabled(True) + frame.EvaluateExpression ("b (4)", lldb.eNoDynamicValues, False) + + threads = lldbutil.get_threads_stopped_at_breakpoint (process, break_in_b) + if len(threads) != 1: + self.fail ("Failed to stop at breakpoint in b when calling b.") + thread = threads[0] + + # So do a step over here to make sure we can still do that: + + thread.StepOver() + + # See that we are still in b: + func_name = thread.GetFrameAtIndex(0).GetFunctionName() + self.assertTrue (func_name == "b", "Should be in 'b', were in %s"%(func_name)) + + # Okay, now if we continue, we will finish off our function call and we should end up back in "a" as if nothing had happened: + process.Continue () + + self.assertTrue (thread.GetFrameAtIndex(0).GetLineEntry().GetLine() == current_line) + self.assertTrue (thread.GetFrameAtIndex(0).GetLineEntry().GetFileSpec() == current_file) + + # Now we are going to test step in targeting a function: + + break_in_b.SetEnabled (False) + + break_before_complex_1 = target.BreakpointCreateBySourceRegex ('// Stop here to try step in targeting b.', self.main_source_spec) + self.assertTrue(break_before_complex_1, VALID_BREAKPOINT) + + break_before_complex_2 = target.BreakpointCreateBySourceRegex ('// Stop here to try step in targeting complex.', self.main_source_spec) + self.assertTrue(break_before_complex_2, VALID_BREAKPOINT) + + break_before_complex_3 = target.BreakpointCreateBySourceRegex ('// Stop here to step targeting b and hitting breakpoint.', self.main_source_spec) + self.assertTrue(break_before_complex_3, VALID_BREAKPOINT) + + break_before_complex_4 = target.BreakpointCreateBySourceRegex ('// Stop here to make sure bogus target steps over.', self.main_source_spec) + self.assertTrue(break_before_complex_4, VALID_BREAKPOINT) + + threads = lldbutil.continue_to_breakpoint(process, break_before_complex_1) + self.assertTrue (len(threads) == 1) + thread = threads[0] + break_before_complex_1.SetEnabled(False) + + thread.StepInto ("b") + self.assertTrue (thread.GetFrameAtIndex(0).GetFunctionName() == "b") + + # Now continue out and stop at the next call to complex. This time step all the way into complex: + threads = lldbutil.continue_to_breakpoint (process, break_before_complex_2) + self.assertTrue (len(threads) == 1) + thread = threads[0] + break_before_complex_2.SetEnabled(False) + + thread.StepInto ("complex") + self.assertTrue (thread.GetFrameAtIndex(0).GetFunctionName() == "complex") + + # Now continue out and stop at the next call to complex. This time enable breakpoints in a and c and then step targeting b: + threads = lldbutil.continue_to_breakpoint (process, break_before_complex_3) + self.assertTrue (len(threads) == 1) + thread = threads[0] + break_before_complex_3.SetEnabled(False) + + break_at_start_of_a = target.BreakpointCreateByName ('a') + break_at_start_of_c = target.BreakpointCreateByName ('c') + + thread.StepInto ("b") + threads = lldbutil.get_stopped_threads(process, lldb.eStopReasonBreakpoint); + + self.assertTrue (len(threads) == 1) + thread = threads[0] + stop_break_id = thread.GetStopReasonDataAtIndex(0) + self.assertTrue(stop_break_id == break_at_start_of_a.GetID() or stop_break_id == break_at_start_of_c.GetID()) + + break_at_start_of_a.SetEnabled(False) + break_at_start_of_c.SetEnabled(False) + + process.Continue() + self.assertTrue (thread.GetFrameAtIndex(0).GetFunctionName() == "b") + + # Now continue out and stop at the next call to complex. This time enable breakpoints in a and c and then step targeting b: + threads = lldbutil.continue_to_breakpoint (process, break_before_complex_4) + self.assertTrue (len(threads) == 1) + thread = threads[0] + break_before_complex_4.SetEnabled(False) + + thread.StepInto("NoSuchFunction") + self.assertTrue (thread.GetFrameAtIndex(0).GetFunctionName() == "main") |