1""" 2Test stopping at a breakpoint in an expression, and unwinding from there. 3""" 4 5import lldb 6from lldbsuite.test.decorators import * 7from lldbsuite.test.lldbtest import * 8from lldbsuite.test import lldbutil 9 10 11class UnwindFromExpressionTest(TestBase): 12 main_spec = lldb.SBFileSpec("main.cpp", False) 13 14 def build_and_run_to_bkpt(self): 15 self.build() 16 17 (target, process, self.thread, bkpt) = lldbutil.run_to_source_breakpoint( 18 self, "// Set a breakpoint here to get started", self.main_spec 19 ) 20 21 # Next set a breakpoint in this function, set up Expression options to stop on 22 # breakpoint hits, and call the function. 23 self.fun_bkpt = self.target().BreakpointCreateBySourceRegex( 24 "// Stop inside the function here.", self.main_spec 25 ) 26 self.assertTrue(self.fun_bkpt, VALID_BREAKPOINT) 27 28 @no_debug_info_test 29 @expectedFailureAll(bugnumber="llvm.org/pr33164") 30 def test_conditional_bktp(self): 31 """ 32 Test conditional breakpoint handling in the IgnoreBreakpoints = False case 33 """ 34 self.build_and_run_to_bkpt() 35 36 self.fun_bkpt.SetCondition("0") # Should not get hit 37 options = lldb.SBExpressionOptions() 38 options.SetIgnoreBreakpoints(False) 39 options.SetUnwindOnError(False) 40 41 main_frame = self.thread.GetFrameAtIndex(0) 42 val = main_frame.EvaluateExpression("second_function(47)", options) 43 self.assertSuccess(val.GetError(), "We did complete the execution.") 44 self.assertEqual(47, val.GetValueAsSigned()) 45 46 @add_test_categories(["pyapi"]) 47 @expectedFlakeyNetBSD 48 def test_unwind_expression(self): 49 """Test unwinding from an expression.""" 50 self.build_and_run_to_bkpt() 51 52 # Run test with varying one thread timeouts to also test the halting 53 # logic in the IgnoreBreakpoints = False case 54 self.do_unwind_test(self.thread, self.fun_bkpt, 1000) 55 self.do_unwind_test(self.thread, self.fun_bkpt, 100000) 56 57 def do_unwind_test(self, thread, bkpt, timeout): 58 # 59 # Use Python API to evaluate expressions while stopped in a stack frame. 60 # 61 main_frame = thread.GetFrameAtIndex(0) 62 63 options = lldb.SBExpressionOptions() 64 options.SetIgnoreBreakpoints(False) 65 options.SetUnwindOnError(False) 66 options.SetOneThreadTimeoutInMicroSeconds(timeout) 67 68 val = main_frame.EvaluateExpression("a_function_to_call()", options) 69 70 self.assertTrue(val.GetError().Fail(), "We did not complete the execution.") 71 error_str = val.GetError().GetCString() 72 self.assertIn( 73 "Expression execution hit a breakpoint: breakpoint", 74 error_str, 75 "And the reason was right.", 76 ) 77 78 thread = lldbutil.get_one_thread_stopped_at_breakpoint(self.process(), bkpt) 79 self.assertTrue(thread.IsValid(), "We are indeed stopped at our breakpoint") 80 81 # Now unwind the expression, and make sure we got back to where we 82 # started. 83 self.assertSuccess( 84 thread.UnwindInnermostExpression(), "We succeeded in unwinding" 85 ) 86 87 cur_frame = thread.GetFrameAtIndex(0) 88 self.assertTrue(cur_frame.IsEqual(main_frame), "We got back to the main frame.") 89