[Lldb-commits] [lldb] [lldb] Add support for large watchpoints in lldb (PR #79962)

David Spickett via lldb-commits lldb-commits at lists.llvm.org
Thu Feb 1 06:12:12 PST 2024


================
@@ -0,0 +1,101 @@
+"""
+Watch a large unaligned memory region that
+lldb will need multiple hardware watchpoints
+to cover.
+"""
+
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class UnalignedLargeWatchpointTestCase(TestBase):
+    def continue_and_report_stop_reason(self, process, iter_str):
+        if self.TraceOn():
+            self.runCmd("script print('continue')")
+        process.Continue()
+        self.assertIn(
+            process.GetState(), [lldb.eStateStopped, lldb.eStateExited], iter_str
+        )
+        thread = process.GetSelectedThread()
+        return thread.GetStopReason()
+
+    NO_DEBUG_INFO_TESTCASE = True
+
+    # Test on 64-bit targets where we probably have
+    # four watchpoint registers that can watch doublewords (8-byte).
+    @skipIf(archs=no_match(["arm64", "arm64e", "aarch64", "x86_64"]))
+    def test_unaligned_large_watchpoint(self):
+        """Test watching an unaligned region of memory that requires multiple watchpoints."""
+        self.build()
+        self.main_source_file = lldb.SBFileSpec("main.c")
+        (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
+            self, "break here", self.main_source_file
+        )
+        self.runCmd("break set -p done")
+        self.runCmd("break set -p exiting")
+
+        frame = thread.GetFrameAtIndex(0)
+
+        array_addr = frame.GetValueForVariablePath("array").GetValueAsUnsigned()
+
+        # Don't assume that the heap allocated array is aligned
+        # to a 1024 byte boundary to begin with, force alignment.
+        # wa_addr = (array_addr + 1024) & ~(1024 - 1)
+        wa_addr = array_addr
+
+        # Now make the start address unaligned.
+        wa_addr = wa_addr + 7
+
+        err = lldb.SBError()
+        wp_opts = lldb.SBWatchpointOptions()
+        wp_opts.SetWatchpointTypeWrite(lldb.eWatchpointWriteTypeOnModify)
+        wp = target.WatchpointCreateByAddress(wa_addr, 22, wp_opts, err)
+        self.assertTrue(wp.IsValid())
+        self.assertSuccess(err)
+        if self.TraceOn():
+            self.runCmd("watch list -v")
+
+        c_count = 0
+        reason = self.continue_and_report_stop_reason(process, "continue #%d" % c_count)
+        while reason == lldb.eStopReasonWatchpoint:
+            c_count = c_count + 1
+            reason = self.continue_and_report_stop_reason(
+                process, "continue #%d" % c_count
+            )
+            self.assertLessEqual(c_count, 22)
+
+        self.assertEqual(c_count, 22)
+        self.expect("watchpoint list -v", substrs=["hit_count = 22"])
+        self.assertEqual(wp.GetHitCount(), 22)
+
+        target.DeleteWatchpoint(wp.GetID())
+
+        # Now try watching a 16 byte variable
+        # (not unaligned, but a good check to do anyway)
+        #
+        frame = thread.GetFrameAtIndex(0)
+        err = lldb.SBError()
+        wp = frame.locals["variable"][0].Watch(True, False, True, err)
----------------
DavidSpickett wrote:

What are the bools here doing?

https://github.com/llvm/llvm-project/pull/79962


More information about the lldb-commits mailing list