| """ |
| Test stopping at a breakpoint in an expression, and unwinding from there. |
| """ |
| |
| from __future__ import print_function |
| |
| |
| import unittest2 |
| |
| import os |
| import time |
| import lldb |
| from lldbsuite.test.decorators import * |
| from lldbsuite.test.lldbtest import * |
| from lldbsuite.test import lldbutil |
| |
| |
| class UnwindFromExpressionTest(TestBase): |
| |
| mydir = TestBase.compute_mydir(__file__) |
| main_spec = lldb.SBFileSpec("main.cpp", False) |
| |
| def build_and_run_to_bkpt(self): |
| self.build() |
| |
| (target, process, self.thread, bkpt) = lldbutil.run_to_source_breakpoint(self, |
| "// Set a breakpoint here to get started", self.main_spec) |
| |
| # Next set a breakpoint in this function, set up Expression options to stop on |
| # breakpoint hits, and call the function. |
| self.fun_bkpt = self.target().BreakpointCreateBySourceRegex( |
| "// Stop inside the function here.", self.main_spec) |
| self.assertTrue(self.fun_bkpt, VALID_BREAKPOINT) |
| |
| |
| @no_debug_info_test |
| @expectedFailureAll(bugnumber="llvm.org/pr33164") |
| def test_conditional_bktp(self): |
| """ |
| Test conditional breakpoint handling in the IgnoreBreakpoints = False case |
| """ |
| self.build_and_run_to_bkpt() |
| |
| self.fun_bkpt.SetCondition("0") # Should not get hit |
| options = lldb.SBExpressionOptions() |
| options.SetIgnoreBreakpoints(False) |
| options.SetUnwindOnError(False) |
| |
| main_frame = self.thread.GetFrameAtIndex(0) |
| val = main_frame.EvaluateExpression("second_function(47)", options) |
| self.assertTrue( |
| val.GetError().Success(), |
| "We did complete the execution.") |
| self.assertEquals(47, val.GetValueAsSigned()) |
| |
| |
| @add_test_categories(['pyapi']) |
| @expectedFailureAll(oslist=["windows"]) |
| def test_unwind_expression(self): |
| """Test unwinding from an expression.""" |
| self.build_and_run_to_bkpt() |
| |
| # Run test with varying one thread timeouts to also test the halting |
| # logic in the IgnoreBreakpoints = False case |
| self.do_unwind_test(self.thread, self.fun_bkpt, 1000) |
| self.do_unwind_test(self.thread, self.fun_bkpt, 100000) |
| |
| def do_unwind_test(self, thread, bkpt, timeout): |
| # |
| # Use Python API to evaluate expressions while stopped in a stack frame. |
| # |
| main_frame = thread.GetFrameAtIndex(0) |
| |
| options = lldb.SBExpressionOptions() |
| options.SetIgnoreBreakpoints(False) |
| options.SetUnwindOnError(False) |
| options.SetOneThreadTimeoutInMicroSeconds(timeout) |
| |
| val = main_frame.EvaluateExpression("a_function_to_call()", options) |
| |
| self.assertTrue( |
| val.GetError().Fail(), |
| "We did not complete the execution.") |
| error_str = val.GetError().GetCString() |
| self.assertTrue( |
| "Execution was interrupted, reason: breakpoint" in error_str, |
| "And the reason was right.") |
| |
| thread = lldbutil.get_one_thread_stopped_at_breakpoint( |
| self.process(), bkpt) |
| self.assertTrue( |
| thread.IsValid(), |
| "We are indeed stopped at our breakpoint") |
| |
| # Now unwind the expression, and make sure we got back to where we |
| # started. |
| error = thread.UnwindInnermostExpression() |
| self.assertTrue(error.Success(), "We succeeded in unwinding") |
| |
| cur_frame = thread.GetFrameAtIndex(0) |
| self.assertTrue( |
| cur_frame.IsEqual(main_frame), |
| "We got back to the main frame.") |