xref: /llvm-project/lldb/test/API/functionalities/watchpoint/large-watchpoint/TestLargeWatchpoint.py (revision 5953532615595918d006ace2ad83fe33d1cd3915)
1"""
2Watch larger-than-8-bytes regions of memory, confirm that
3writes to those regions are detected.
4"""
5
6
7import lldb
8from lldbsuite.test.decorators import *
9from lldbsuite.test.lldbtest import *
10from lldbsuite.test import lldbutil
11
12
13class UnalignedWatchpointTestCase(TestBase):
14    def continue_and_report_stop_reason(self, process, iter_str):
15        process.Continue()
16        self.assertIn(
17            process.GetState(), [lldb.eStateStopped, lldb.eStateExited], iter_str
18        )
19        thread = process.GetSelectedThread()
20        return thread.GetStopReason()
21
22    NO_DEBUG_INFO_TESTCASE = True
23
24    # debugserver on AArch64 has this feature.
25    @skipIf(archs=no_match(["arm64", "arm64e", "aarch64"]))
26    @skipUnlessDarwin
27
28    # debugserver only gained the ability to watch larger regions
29    # with this patch.
30    @skipIfOutOfTreeDebugserver
31    def test_large_watchpoint(self):
32        """Test watchpoint that covers a large region of memory."""
33        self.build()
34        self.main_source_file = lldb.SBFileSpec("main.c")
35        (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
36            self, "break here", self.main_source_file
37        )
38
39        frame = thread.GetFrameAtIndex(0)
40
41        array_addr = frame.GetValueForVariablePath("array").GetValueAsUnsigned()
42
43        # watch 256 uint32_t elements in the middle of the array,
44        # don't assume that the heap allocated array is aligned
45        # to a 1024 byte boundary to begin with, force alignment.
46        wa_256_addr = (array_addr + 1024) & ~(1024 - 1)
47        err = lldb.SBError()
48        wp_opts = lldb.SBWatchpointOptions()
49        wp_opts.SetWatchpointTypeWrite(lldb.eWatchpointWriteTypeOnModify)
50        wp = target.WatchpointCreateByAddress(wa_256_addr, 1024, wp_opts, err)
51        self.assertTrue(wp.IsValid())
52        self.assertSuccess(err)
53
54        c_count = 0
55        reason = self.continue_and_report_stop_reason(process, "continue #%d" % c_count)
56        while reason == lldb.eStopReasonWatchpoint:
57            c_count = c_count + 1
58            reason = self.continue_and_report_stop_reason(
59                process, "continue #%d" % c_count
60            )
61            self.assertLessEqual(c_count, 16)
62
63        self.assertEqual(c_count, 16)
64