63 lines · python
1"""2Test finish out of an empty function (may be one-instruction long)3"""4 5import lldb6from lldbsuite.test.decorators import *7from lldbsuite.test.lldbtest import *8from lldbsuite.test import lldbutil9 10 11class FinishFromEmptyFunctionTestCase(TestBase):12 NO_DEBUG_INFO_TESTCASE = True13 14 @skipIf(compiler="clang", compiler_version=['<', '17.0'])15 def test_finish_from_empty_function(self):16 """Test that when stopped at a breakpoint located at the last instruction17 of a function, finish leaves it correctly."""18 self.build()19 target, _, thread, _ = lldbutil.run_to_source_breakpoint(20 self, "// Set breakpoint here", lldb.SBFileSpec("main.c")21 )22 # Find the address of the last instruction of 'done()' and set a breakpoint there.23 # Even though 'done()' is empty, it may contain prologue and epilogue code, so24 # simply setting a breakpoint at the function can place it before 'ret'.25 error = lldb.SBError()26 ret_bp_addr = lldb.SBAddress()27 while True:28 thread.StepInstruction(False, error)29 self.assertTrue(error.Success())30 frame = thread.GetSelectedFrame()31 if "done" in frame.GetFunctionName():32 ret_bp_addr = frame.GetPCAddress()33 elif ret_bp_addr.IsValid():34 # The entire function 'done()' has been stepped through, so 'ret_bp_addr'35 # now contains the address of its last instruction, i.e. 'ret'.36 break37 ret_bp = target.BreakpointCreateByAddress(ret_bp_addr.GetLoadAddress(target))38 self.assertTrue(ret_bp.IsValid())39 # Resume the execution and hit the new breakpoint.40 self.runCmd("cont")41 if self.TraceOn():42 self.runCmd("bt")43 44 correct_stepped_out_line = line_number("main.c", "leaving main")45 return_statement_line = line_number("main.c", "return 0")46 safety_bp = target.BreakpointCreateByLocation(47 lldb.SBFileSpec("main.c"), return_statement_line48 )49 self.assertTrue(safety_bp.IsValid())50 51 thread.StepOut(error)52 self.assertTrue(error.Success())53 54 if self.TraceOn():55 self.runCmd("bt")56 57 frame = thread.GetSelectedFrame()58 self.assertEqual(59 frame.line_entry.GetLine(),60 correct_stepped_out_line,61 "Step-out lost control of execution, ran too far",62 )63