105 lines · python
1"""2Watch a large unaligned memory region that3lldb will need multiple hardware watchpoints4to cover.5"""6 7 8import lldb9from lldbsuite.test.decorators import *10from lldbsuite.test.lldbtest import *11from lldbsuite.test import lldbutil12 13 14class UnalignedLargeWatchpointTestCase(TestBase):15 def continue_and_report_stop_reason(self, process, iter_str):16 if self.TraceOn():17 self.runCmd("script print('continue')")18 process.Continue()19 self.assertIn(20 process.GetState(), [lldb.eStateStopped, lldb.eStateExited], iter_str21 )22 thread = process.GetSelectedThread()23 return thread.GetStopReason()24 25 NO_DEBUG_INFO_TESTCASE = True26 27 # The Windows process plugins haven't been updated to break28 # watchpoints into WatchpointResources yet.29 @skipIfWindows30 31 # Test on 64-bit targets where we probably have32 # four watchpoint registers that can watch doublewords (8-byte).33 @skipIf(archs=no_match(["arm64", "arm64e", "aarch64", "x86_64"]))34 def test_unaligned_large_watchpoint(self):35 """Test watching an unaligned region of memory that requires multiple watchpoints."""36 self.build()37 self.main_source_file = lldb.SBFileSpec("main.c")38 target, process, thread, bkpt = lldbutil.run_to_source_breakpoint(39 self, "break here", self.main_source_file40 )41 self.runCmd("break set -p done")42 self.runCmd("break set -p exiting")43 44 frame = thread.GetFrameAtIndex(0)45 46 array_addr = frame.GetValueForVariablePath("array").GetValueAsUnsigned()47 48 # Don't assume that the heap allocated array is aligned49 # to a 1024 byte boundary to begin with, force alignment.50 # wa_addr = (array_addr + 1024) & ~(1024 - 1)51 wa_addr = array_addr52 53 # Now make the start address unaligned.54 wa_addr = wa_addr + 755 56 err = lldb.SBError()57 wp_opts = lldb.SBWatchpointOptions()58 wp_opts.SetWatchpointTypeWrite(lldb.eWatchpointWriteTypeOnModify)59 wp = target.WatchpointCreateByAddress(wa_addr, 22, wp_opts, err)60 self.assertTrue(wp.IsValid())61 self.assertSuccess(err)62 if self.TraceOn():63 self.runCmd("watch list -v")64 65 c_count = 066 reason = self.continue_and_report_stop_reason(process, "continue #%d" % c_count)67 while reason == lldb.eStopReasonWatchpoint:68 c_count = c_count + 169 reason = self.continue_and_report_stop_reason(70 process, "continue #%d" % c_count71 )72 self.assertLessEqual(c_count, 22)73 74 self.assertEqual(c_count, 22)75 self.expect("watchpoint list -v", substrs=["hit_count = 22"])76 self.assertEqual(wp.GetHitCount(), 22)77 78 target.DeleteWatchpoint(wp.GetID())79 80 # Now try watching a 16 byte variable81 # (not unaligned, but a good check to do anyway)82 frame = thread.GetFrameAtIndex(0)83 err = lldb.SBError()84 wp = frame.locals["variable"][0].Watch(True, False, True, err)85 self.assertSuccess(err)86 if self.TraceOn():87 self.runCmd("frame select 0")88 self.runCmd("watchpoint list")89 90 c_count = 091 reason = self.continue_and_report_stop_reason(process, "continue #%d" % c_count)92 while reason == lldb.eStopReasonWatchpoint:93 c_count = c_count + 194 reason = self.continue_and_report_stop_reason(95 process, "continue #%d" % c_count96 )97 self.assertLessEqual(c_count, 4)98 99 if self.TraceOn():100 self.runCmd("frame select 0")101 102 self.assertEqual(c_count, 4)103 self.expect("watchpoint list -v", substrs=["hit_count = 4"])104 self.assertEqual(wp.GetHitCount(), 4)105