66 lines · python
1"""2Watch 4 bytes which spawn two doubleword aligned regions.3On a target that supports 8 byte watchpoints, this will4need to be implemented with a hardware watchpoint on both5doublewords.6"""7 8 9import lldb10from lldbsuite.test.decorators import *11from lldbsuite.test.lldbtest import *12from lldbsuite.test import lldbutil13 14 15class UnalignedWatchpointTestCase(TestBase):16 def hit_watchpoint_and_continue(self, process, iter_str):17 process.Continue()18 self.assertEqual(process.GetState(), lldb.eStateStopped, iter_str)19 thread = process.GetSelectedThread()20 self.assertEqual(thread.GetStopReason(), lldb.eStopReasonWatchpoint, iter_str)21 self.assertEqual(thread.GetStopReasonDataCount(), 1, iter_str)22 wp_num = thread.GetStopReasonDataAtIndex(0)23 self.assertEqual(wp_num, 1, iter_str)24 25 NO_DEBUG_INFO_TESTCASE = True26 27 # debugserver on AArch64 has this feature.28 @skipIf(archs=no_match(["arm64", "arm64e", "aarch64"]))29 @skipUnlessDarwin30 # debugserver only started returning an exception address within31 # a range lldb expects in https://reviews.llvm.org/D147820 2023-04-12.32 # older debugservers will return the base address of the doubleword33 # which lldb doesn't understand, and will stop executing without a34 # proper stop reason.35 def test_unaligned_watchpoint(self):36 """Test a watchpoint that is handled by two hardware watchpoint registers."""37 self.build()38 self.main_source_file = lldb.SBFileSpec("main.c")39 (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(40 self, "break here", self.main_source_file41 )42 43 thread.StepOver()44 45 frame = thread.GetFrameAtIndex(0)46 47 a_bytebuf_6 = frame.GetValueForVariablePath("a.bytebuf[6]")48 a_bytebuf_6_addr = a_bytebuf_6.GetAddress().GetLoadAddress(target)49 err = lldb.SBError()50 wp_opts = lldb.SBWatchpointOptions()51 wp_opts.SetWatchpointTypeWrite(lldb.eWatchpointWriteTypeOnModify)52 wp = target.WatchpointCreateByAddress(a_bytebuf_6_addr, 4, wp_opts, err)53 self.assertTrue(err.Success())54 self.assertTrue(wp.IsEnabled())55 self.assertEqual(wp.GetWatchSize(), 4)56 self.assertGreater(57 wp.GetWatchAddress() % 8, 4, "watched region spans two doublewords"58 )59 60 # We will hit our watchpoint 6 times during the execution61 # of the inferior. If the remote stub does not actually split62 # the watched region into two doubleword watchpoints, we will63 # exit before we get to 6 watchpoint hits.64 for i in range(1, 7):65 self.hit_watchpoint_and_continue(process, "wp hit number %s" % i)66