1"""Test stepping over watchpoints and instruction stepping past watchpoints.""" 2 3 4import lldb 5from lldbsuite.test.decorators import * 6from lldbsuite.test.lldbtest import * 7from lldbsuite.test import lldbutil 8 9 10class TestStepOverWatchpoint(TestBase): 11 NO_DEBUG_INFO_TESTCASE = True 12 13 def get_to_start(self, bkpt_text): 14 """Test stepping over watchpoints and instruction stepping past watchpoints..""" 15 self.build() 16 target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( 17 self, bkpt_text, lldb.SBFileSpec("main.c") 18 ) 19 return (target, process, thread, frame, read_watchpoint) 20 21 @add_test_categories(["basic_process"]) 22 @expectedFailureAll( 23 macos_version=["<", "14.4"], 24 archs=["aarch64", "arm"], 25 bugnumber="<rdar://problem/106868647>", 26 ) 27 def test_step_over_read_watchpoint(self): 28 self.build() 29 target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( 30 self, "break here for read watchpoints", lldb.SBFileSpec("main.c") 31 ) 32 33 frame = thread.GetFrameAtIndex(0) 34 self.assertTrue(frame.IsValid(), "Failed to get frame.") 35 36 read_value = frame.FindValue("g_watch_me_read", lldb.eValueTypeVariableGlobal) 37 self.assertTrue(read_value.IsValid(), "Failed to find read value.") 38 39 error = lldb.SBError() 40 41 # resolve_location=True, read=True, write=False 42 read_watchpoint = read_value.Watch(True, True, False, error) 43 self.assertSuccess(error, "Error while setting watchpoint") 44 self.assertTrue(read_watchpoint, "Failed to set read watchpoint.") 45 46 # Disable the breakpoint we hit so we don't muddy the waters with 47 # stepping off from the breakpoint: 48 bkpt.SetEnabled(False) 49 50 thread.StepOver() 51 self.assertStopReason( 52 thread.GetStopReason(), 53 lldb.eStopReasonWatchpoint, 54 STOPPED_DUE_TO_WATCHPOINT, 55 ) 56 self.assertEqual(thread.GetStopDescription(20), "watchpoint 1") 57 58 process.Continue() 59 self.assertState(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) 60 self.assertEqual(thread.GetStopDescription(20), "step over") 61 62 self.step_inst_for_watchpoint(1) 63 64 @add_test_categories(["basic_process"]) 65 @expectedFailureAll( 66 macos_version=["<", "14.4"], 67 archs=["aarch64", "arm"], 68 bugnumber="<rdar://problem/106868647>", 69 ) 70 def test_step_over_write_watchpoint(self): 71 self.build() 72 target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( 73 self, "break here for modify watchpoints", lldb.SBFileSpec("main.c") 74 ) 75 76 # Disable the breakpoint we hit so we don't muddy the waters with 77 # stepping off from the breakpoint: 78 bkpt.SetEnabled(False) 79 80 frame = thread.GetFrameAtIndex(0) 81 self.assertTrue(frame.IsValid(), "Failed to get frame.") 82 83 write_value = frame.FindValue("g_watch_me_write", lldb.eValueTypeVariableGlobal) 84 self.assertTrue(write_value, "Failed to find write value.") 85 86 error = lldb.SBError() 87 # resolve_location=True, read=False, modify=True 88 write_watchpoint = write_value.Watch(True, False, True, error) 89 self.assertTrue(write_watchpoint, "Failed to set write watchpoint.") 90 self.assertSuccess(error, "Error while setting watchpoint") 91 92 thread.StepOver() 93 self.assertStopReason( 94 thread.GetStopReason(), 95 lldb.eStopReasonWatchpoint, 96 STOPPED_DUE_TO_WATCHPOINT, 97 ) 98 self.assertEqual(thread.GetStopDescription(20), "watchpoint 1") 99 100 process.Continue() 101 self.assertState(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED) 102 self.assertEqual(thread.GetStopDescription(20), "step over") 103 104 self.step_inst_for_watchpoint(1) 105 106 def step_inst_for_watchpoint(self, wp_id): 107 watchpoint_hit = False 108 current_line = self.frame().GetLineEntry().GetLine() 109 while self.frame().GetLineEntry().GetLine() == current_line: 110 self.thread().StepInstruction(False) # step_over=False 111 stop_reason = self.thread().GetStopReason() 112 if stop_reason == lldb.eStopReasonWatchpoint: 113 self.assertFalse(watchpoint_hit, "Watchpoint already hit.") 114 expected_stop_desc = "watchpoint %d" % wp_id 115 actual_stop_desc = self.thread().GetStopDescription(20) 116 self.assertEqual( 117 actual_stop_desc, expected_stop_desc, "Watchpoint ID didn't match." 118 ) 119 watchpoint_hit = True 120 else: 121 self.assertStopReason( 122 stop_reason, lldb.eStopReasonPlanComplete, STOPPED_DUE_TO_STEP_IN 123 ) 124 self.assertTrue(watchpoint_hit, "Watchpoint never hit.") 125