119 lines · python
1"""Test stepping over watchpoints and instruction stepping past watchpoints."""2 3 4import lldb5from lldbsuite.test.decorators import *6from lldbsuite.test.lldbtest import *7from lldbsuite.test import lldbutil8 9 10class TestStepOverWatchpoint(TestBase):11 NO_DEBUG_INFO_TESTCASE = True12 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 # kernel disables wp's over instruction step, fixed in macOS 14.4.23 @skipIf(macos_version=["<", "14.4"])24 def test_step_over_read_watchpoint(self):25 self.build()26 target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(27 self, "break here for read watchpoints", lldb.SBFileSpec("main.c")28 )29 30 frame = thread.GetFrameAtIndex(0)31 self.assertTrue(frame.IsValid(), "Failed to get frame.")32 33 read_value = frame.FindValue("g_watch_me_read", lldb.eValueTypeVariableGlobal)34 self.assertTrue(read_value.IsValid(), "Failed to find read value.")35 36 error = lldb.SBError()37 38 # resolve_location=True, read=True, write=False39 read_watchpoint = read_value.Watch(True, True, False, error)40 self.assertSuccess(error, "Error while setting watchpoint")41 self.assertTrue(read_watchpoint, "Failed to set read watchpoint.")42 43 # Disable the breakpoint we hit so we don't muddy the waters with44 # stepping off from the breakpoint:45 bkpt.SetEnabled(False)46 47 thread.StepOver()48 self.assertStopReason(49 thread.GetStopReason(),50 lldb.eStopReasonWatchpoint,51 STOPPED_DUE_TO_WATCHPOINT,52 )53 self.assertEqual(thread.stop_description, "watchpoint 1")54 55 process.Continue()56 self.assertState(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)57 self.assertEqual(thread.stop_description, "step over")58 59 self.step_inst_for_watchpoint(1)60 61 @add_test_categories(["basic_process"])62 # kernel disables wp's over instruction step, fixed in macOS 14.4.63 @skipIf(macos_version=["<", "14.4"])64 def test_step_over_write_watchpoint(self):65 self.build()66 target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(67 self, "break here for modify watchpoints", lldb.SBFileSpec("main.c")68 )69 70 # Disable the breakpoint we hit so we don't muddy the waters with71 # stepping off from the breakpoint:72 bkpt.SetEnabled(False)73 74 frame = thread.GetFrameAtIndex(0)75 self.assertTrue(frame.IsValid(), "Failed to get frame.")76 77 write_value = frame.FindValue("g_watch_me_write", lldb.eValueTypeVariableGlobal)78 self.assertTrue(write_value, "Failed to find write value.")79 80 error = lldb.SBError()81 # resolve_location=True, read=False, modify=True82 write_watchpoint = write_value.Watch(True, False, True, error)83 self.assertTrue(write_watchpoint, "Failed to set write watchpoint.")84 self.assertSuccess(error, "Error while setting watchpoint")85 86 thread.StepOver()87 self.assertStopReason(88 thread.GetStopReason(),89 lldb.eStopReasonWatchpoint,90 STOPPED_DUE_TO_WATCHPOINT,91 )92 self.assertEqual(thread.stop_description, "watchpoint 1")93 94 process.Continue()95 self.assertState(process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)96 self.assertEqual(thread.stop_description, "step over")97 98 self.step_inst_for_watchpoint(1)99 100 def step_inst_for_watchpoint(self, wp_id):101 watchpoint_hit = False102 current_line = self.frame().GetLineEntry().GetLine()103 while self.frame().GetLineEntry().GetLine() == current_line:104 self.thread().StepInstruction(False) # step_over=False105 stop_reason = self.thread().GetStopReason()106 if stop_reason == lldb.eStopReasonWatchpoint:107 self.assertFalse(watchpoint_hit, "Watchpoint already hit.")108 expected_stop_desc = "watchpoint %d" % wp_id109 actual_stop_desc = self.thread().stop_description110 self.assertEqual(111 actual_stop_desc, expected_stop_desc, "Watchpoint ID didn't match."112 )113 watchpoint_hit = True114 else:115 self.assertStopReason(116 stop_reason, lldb.eStopReasonPlanComplete, STOPPED_DUE_TO_STEP_IN117 )118 self.assertTrue(watchpoint_hit, "Watchpoint never hit.")119