127 lines · python
1"""2Test that we handle breakpoints on consecutive instructions correctly.3"""4 5import lldb6from lldbsuite.test.decorators import *7from lldbsuite.test.lldbtest import *8from lldbsuite.test import lldbutil9 10 11class ConsecutiveBreakpointsTestCase(TestBase):12 def prepare_test(self):13 self.build()14 15 (16 self.target,17 self.process,18 self.thread,19 bkpt,20 ) = lldbutil.run_to_source_breakpoint(21 self, "Set breakpoint here", lldb.SBFileSpec("main.cpp")22 )23 24 # Set breakpoint to the next instruction25 frame = self.thread.GetFrameAtIndex(0)26 27 address = frame.GetPCAddress()28 instructions = self.target.ReadInstructions(address, 2)29 self.assertEqual(len(instructions), 2)30 self.bkpt_address = instructions[1].GetAddress()31 self.breakpoint2 = self.target.BreakpointCreateByAddress(32 self.bkpt_address.GetLoadAddress(self.target)33 )34 self.assertTrue(35 self.breakpoint2 and self.breakpoint2.GetNumLocations() == 1,36 VALID_BREAKPOINT,37 )38 39 def finish_test(self):40 # Run the process until termination41 self.process.Continue()42 self.assertState(self.process.GetState(), lldb.eStateExited)43 44 @no_debug_info_test45 def test_continue(self):46 """Test that continue stops at the second breakpoint."""47 self.prepare_test()48 49 self.process.Continue()50 self.assertState(self.process.GetState(), lldb.eStateStopped)51 # We should be stopped at the second breakpoint52 self.thread = lldbutil.get_one_thread_stopped_at_breakpoint(53 self.process, self.breakpoint254 )55 self.assertIsNotNone(56 self.thread, "Expected one thread to be stopped at breakpoint 2"57 )58 59 self.finish_test()60 61 @no_debug_info_test62 def test_single_step(self):63 """Test that single step stops at the second breakpoint."""64 self.prepare_test()65 66 # Instruction step to the next instruction67 # We haven't executed breakpoint2 yet, we're sitting at it now.68 step_over = False69 self.thread.StepInstruction(step_over)70 71 step_over = False72 self.thread.StepInstruction(step_over)73 74 # We've now hit the breakpoint and this StepInstruction has75 # been interrupted, it is still sitting on the thread plan stack.76 77 self.assertState(self.process.GetState(), lldb.eStateStopped)78 self.assertEqual(79 self.thread.GetFrameAtIndex(0).GetPCAddress().GetLoadAddress(self.target),80 self.bkpt_address.GetLoadAddress(self.target),81 )82 83 # One more instruction to complete the Step that was interrupted84 # earlier.85 self.thread.StepInstruction(step_over)86 strm = lldb.SBStream()87 self.thread.GetDescription(strm)88 self.assertIn("instruction step into", strm.GetData())89 self.assertIsNotNone(self.thread, "Expected to see that step-in had completed")90 91 self.finish_test()92 93 @no_debug_info_test94 @skipIf(95 oslist=["windows"],96 archs=["x86_64"],97 bugnumber="github.com/llvm/llvm-project/issues/138083",98 )99 def test_single_step_thread_specific(self):100 """Test that single step stops, even though the second breakpoint is not valid."""101 self.prepare_test()102 103 # Choose a thread other than the current one. A non-existing thread is104 # fine.105 thread_index = self.process.GetNumThreads() + 1106 self.assertFalse(self.process.GetThreadAtIndex(thread_index).IsValid())107 self.breakpoint2.SetThreadIndex(thread_index)108 109 step_over = False110 self.thread.StepInstruction(step_over)111 112 self.assertState(self.process.GetState(), lldb.eStateStopped)113 self.assertEqual(114 self.thread.GetFrameAtIndex(0).GetPCAddress().GetLoadAddress(self.target),115 self.bkpt_address.GetLoadAddress(self.target),116 )117 self.assertEqual(118 self.thread.GetStopReason(),119 lldb.eStopReasonPlanComplete,120 "Stop reason should be 'plan complete'",121 )122 123 # Hit our second breakpoint124 self.process.Continue()125 126 self.finish_test()127