1""" 2Test that we handle breakpoints on consecutive instructions correctly. 3""" 4 5 6import lldb 7from lldbsuite.test.decorators import * 8from lldbsuite.test.lldbtest import * 9from lldbsuite.test import lldbutil 10 11 12class ConsecutiveBreakpointsTestCase(TestBase): 13 def prepare_test(self): 14 self.build() 15 16 ( 17 self.target, 18 self.process, 19 self.thread, 20 bkpt, 21 ) = lldbutil.run_to_source_breakpoint( 22 self, "Set breakpoint here", lldb.SBFileSpec("main.cpp") 23 ) 24 25 # Set breakpoint to the next instruction 26 frame = self.thread.GetFrameAtIndex(0) 27 28 address = frame.GetPCAddress() 29 instructions = self.target.ReadInstructions(address, 2) 30 self.assertEqual(len(instructions), 2) 31 self.bkpt_address = instructions[1].GetAddress() 32 self.breakpoint2 = self.target.BreakpointCreateByAddress( 33 self.bkpt_address.GetLoadAddress(self.target) 34 ) 35 self.assertTrue( 36 self.breakpoint2 and self.breakpoint2.GetNumLocations() == 1, 37 VALID_BREAKPOINT, 38 ) 39 40 def finish_test(self): 41 # Run the process until termination 42 self.process.Continue() 43 self.assertState(self.process.GetState(), lldb.eStateExited) 44 45 @no_debug_info_test 46 def test_continue(self): 47 """Test that continue stops at the second breakpoint.""" 48 self.prepare_test() 49 50 self.process.Continue() 51 self.assertState(self.process.GetState(), lldb.eStateStopped) 52 # We should be stopped at the second breakpoint 53 self.thread = lldbutil.get_one_thread_stopped_at_breakpoint( 54 self.process, self.breakpoint2 55 ) 56 self.assertIsNotNone( 57 self.thread, "Expected one thread to be stopped at breakpoint 2" 58 ) 59 60 self.finish_test() 61 62 @no_debug_info_test 63 def test_single_step(self): 64 """Test that single step stops at the second breakpoint.""" 65 self.prepare_test() 66 67 step_over = False 68 self.thread.StepInstruction(step_over) 69 70 self.assertState(self.process.GetState(), lldb.eStateStopped) 71 self.assertEqual( 72 self.thread.GetFrameAtIndex(0).GetPCAddress().GetLoadAddress(self.target), 73 self.bkpt_address.GetLoadAddress(self.target), 74 ) 75 self.thread = lldbutil.get_one_thread_stopped_at_breakpoint( 76 self.process, self.breakpoint2 77 ) 78 self.assertIsNotNone( 79 self.thread, "Expected one thread to be stopped at breakpoint 2" 80 ) 81 82 self.finish_test() 83 84 @no_debug_info_test 85 def test_single_step_thread_specific(self): 86 """Test that single step stops, even though the second breakpoint is not valid.""" 87 self.prepare_test() 88 89 # Choose a thread other than the current one. A non-existing thread is 90 # fine. 91 thread_index = self.process.GetNumThreads() + 1 92 self.assertFalse(self.process.GetThreadAtIndex(thread_index).IsValid()) 93 self.breakpoint2.SetThreadIndex(thread_index) 94 95 step_over = False 96 self.thread.StepInstruction(step_over) 97 98 self.assertState(self.process.GetState(), lldb.eStateStopped) 99 self.assertEqual( 100 self.thread.GetFrameAtIndex(0).GetPCAddress().GetLoadAddress(self.target), 101 self.bkpt_address.GetLoadAddress(self.target), 102 ) 103 self.assertEqual( 104 self.thread.GetStopReason(), 105 lldb.eStopReasonPlanComplete, 106 "Stop reason should be 'plan complete'", 107 ) 108 109 self.finish_test() 110