[Lldb-commits] [lldb] [lldb] Speed up FindInMemory tests (PR #111951)

Igor Kudrin via lldb-commits lldb-commits at lists.llvm.org
Sat Oct 12 14:31:09 PDT 2024


https://github.com/igorkudrin updated https://github.com/llvm/llvm-project/pull/111951

>From e027444340be4020002126da0d2c8a705c2c7e3f Mon Sep 17 00:00:00 2001
From: Igor Kudrin <ikudrin at accesssoftek.com>
Date: Thu, 10 Oct 2024 20:27:10 -0700
Subject: [PATCH 1/2] [lldb] Speed up FindInMemory tests

A memory region can be relatively large. Searching for a value in the
entire region is time-consuming, especially when running tests against
a remote target, because the memory data is transferred in small chunks
over a relatively slow GDB Remote Protocol. The patch limits the address
range to be searched to 2K, which seems sufficient for these tests. In
my setup, for local runs, these tests now take half the time they did
before the patch. For a remote target, the improvement is even more
significant.
---
 .../find_in_memory/TestFindInMemory.py        | 10 ++--
 .../find_in_memory/TestFindRangesInMemory.py  | 16 +++---
 .../find_in_memory/address_ranges_helper.py   | 50 ++++++++++++-------
 3 files changed, 45 insertions(+), 31 deletions(-)

diff --git a/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py b/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py
index 9ab4619b1f8f4f..04e807c5c6201d 100644
--- a/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py
+++ b/lldb/test/API/python_api/find_in_memory/TestFindInMemory.py
@@ -55,7 +55,7 @@ def test_find_in_memory_ok(self):
         error = lldb.SBError()
         addr = self.process.FindInMemory(
             SINGLE_INSTANCE_PATTERN_STACK,
-            GetStackRange(self),
+            GetStackRange(self, True),
             1,
             error,
         )
@@ -70,7 +70,7 @@ def test_find_in_memory_double_instance_ok(self):
         error = lldb.SBError()
         addr = self.process.FindInMemory(
             DOUBLE_INSTANCE_PATTERN_HEAP,
-            GetHeapRanges(self)[0],
+            GetHeapRanges(self, True)[0],
             1,
             error,
         )
@@ -86,7 +86,7 @@ def test_find_in_memory_invalid_alignment(self):
         error = lldb.SBError()
         addr = self.process.FindInMemory(
             SINGLE_INSTANCE_PATTERN_STACK,
-            GetStackRange(self),
+            GetStackRange(self, True),
             0,
             error,
         )
@@ -118,7 +118,7 @@ def test_find_in_memory_invalid_buffer(self):
         error = lldb.SBError()
         addr = self.process.FindInMemory(
             "",
-            GetStackRange(self),
+            GetStackRange(self, True),
             1,
             error,
         )
@@ -131,7 +131,7 @@ def test_find_in_memory_unaligned(self):
         self.assertTrue(self.process, PROCESS_IS_VALID)
         self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
         error = lldb.SBError()
-        range = GetAlignedRange(self)
+        range = GetAlignedRange(self, True)
 
         # First we make sure the pattern is found with alignment 1
         addr = self.process.FindInMemory(
diff --git a/lldb/test/API/python_api/find_in_memory/TestFindRangesInMemory.py b/lldb/test/API/python_api/find_in_memory/TestFindRangesInMemory.py
index 31bc0e99f4914f..895c527430f218 100644
--- a/lldb/test/API/python_api/find_in_memory/TestFindRangesInMemory.py
+++ b/lldb/test/API/python_api/find_in_memory/TestFindRangesInMemory.py
@@ -30,7 +30,7 @@ def test_find_ranges_in_memory_two_matches(self):
         self.assertTrue(self.process, PROCESS_IS_VALID)
         self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
 
-        addr_ranges = GetHeapRanges(self)
+        addr_ranges = GetHeapRanges(self, True)
         error = lldb.SBError()
         matches = self.process.FindRangesInMemory(
             DOUBLE_INSTANCE_PATTERN_HEAP,
@@ -48,7 +48,7 @@ def test_find_ranges_in_memory_one_match(self):
         self.assertTrue(self.process, PROCESS_IS_VALID)
         self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
 
-        addr_ranges = GetStackRanges(self)
+        addr_ranges = GetStackRanges(self, True)
         error = lldb.SBError()
         matches = self.process.FindRangesInMemory(
             SINGLE_INSTANCE_PATTERN_STACK,
@@ -66,7 +66,7 @@ def test_find_ranges_in_memory_one_match_multiple_ranges(self):
         self.assertTrue(self.process, PROCESS_IS_VALID)
         self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
 
-        addr_ranges = GetRanges(self)
+        addr_ranges = GetRanges(self, True)
         addr_ranges.Append(lldb.SBAddressRange())
         self.assertGreater(addr_ranges.GetSize(), 2)
         error = lldb.SBError()
@@ -86,7 +86,7 @@ def test_find_ranges_in_memory_one_match_max(self):
         self.assertTrue(self.process, PROCESS_IS_VALID)
         self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
 
-        addr_ranges = GetHeapRanges(self)
+        addr_ranges = GetHeapRanges(self, True)
         error = lldb.SBError()
         matches = self.process.FindRangesInMemory(
             DOUBLE_INSTANCE_PATTERN_HEAP,
@@ -104,7 +104,7 @@ def test_find_ranges_in_memory_invalid_alignment(self):
         self.assertTrue(self.process, PROCESS_IS_VALID)
         self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
 
-        addr_ranges = GetHeapRanges(self)
+        addr_ranges = GetHeapRanges(self, True)
         error = lldb.SBError()
         matches = self.process.FindRangesInMemory(
             DOUBLE_INSTANCE_PATTERN_HEAP,
@@ -160,7 +160,7 @@ def test_find_ranges_in_memory_invalid_buffer(self):
         self.assertTrue(self.process, PROCESS_IS_VALID)
         self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
 
-        addr_ranges = GetHeapRanges(self)
+        addr_ranges = GetHeapRanges(self, True)
         error = lldb.SBError()
         matches = self.process.FindRangesInMemory(
             "",
@@ -178,7 +178,7 @@ def test_find_ranges_in_memory_invalid_max_matches(self):
         self.assertTrue(self.process, PROCESS_IS_VALID)
         self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
 
-        addr_ranges = GetHeapRanges(self)
+        addr_ranges = GetHeapRanges(self, True)
         error = lldb.SBError()
         matches = self.process.FindRangesInMemory(
             DOUBLE_INSTANCE_PATTERN_HEAP,
@@ -197,7 +197,7 @@ def test_find_in_memory_unaligned(self):
         self.assertState(self.process.GetState(), lldb.eStateStopped, PROCESS_STOPPED)
 
         addr_ranges = lldb.SBAddressRangeList()
-        addr_ranges.Append(GetAlignedRange(self))
+        addr_ranges.Append(GetAlignedRange(self, True))
         error = lldb.SBError()
 
         matches = self.process.FindRangesInMemory(
diff --git a/lldb/test/API/python_api/find_in_memory/address_ranges_helper.py b/lldb/test/API/python_api/find_in_memory/address_ranges_helper.py
index 810fb9fee38615..ac8c6c9e15f1ca 100644
--- a/lldb/test/API/python_api/find_in_memory/address_ranges_helper.py
+++ b/lldb/test/API/python_api/find_in_memory/address_ranges_helper.py
@@ -6,27 +6,30 @@
 UNALIGNED_INSTANCE_PATTERN_HEAP = ALIGNED_INSTANCE_PATTERN_HEAP[1:]
 
 
-def GetAlignedRange(test_base):
+def GetAlignedRange(test_base, shrink=False):
     frame = test_base.thread.GetSelectedFrame()
     ex = frame.EvaluateExpression("aligned_string_ptr")
     test_base.assertTrue(ex.IsValid())
-    return GetRangeFromAddrValue(test_base, ex)
+    return GetRangeFromAddrValue(test_base, ex, shrink)
 
 
-def GetStackRange(test_base):
+def GetStackRange(test_base, shrink=False):
     frame = test_base.thread.GetSelectedFrame()
     ex = frame.EvaluateExpression("&stack_pointer")
     test_base.assertTrue(ex.IsValid())
-    return GetRangeFromAddrValue(test_base, ex)
+    return GetRangeFromAddrValue(test_base, ex, shrink)
 
 
-def GetStackRanges(test_base):
+def GetStackRanges(test_base, shrink=False):
     addr_ranges = lldb.SBAddressRangeList()
     addr_ranges.Append(GetStackRange(test_base))
     return addr_ranges
 
 
-def GetRangeFromAddrValue(test_base, addr):
+def GetRangeFromAddrValue(test_base, addr, shrink=False):
+    """Return the address range containing 'addr'.
+    If 'shrink' is True, the size of the region will not exceed 2K.
+    """
     region = lldb.SBMemoryRegionInfo()
     test_base.assertTrue(
         test_base.process.GetMemoryRegionInfo(
@@ -37,37 +40,48 @@ def GetRangeFromAddrValue(test_base, addr):
     test_base.assertTrue(region.IsReadable())
     test_base.assertFalse(region.IsExecutable())
 
-    address_start = lldb.SBAddress(region.GetRegionBase(), test_base.target)
-    stack_size = region.GetRegionEnd() - region.GetRegionBase()
-    return lldb.SBAddressRange(address_start, stack_size)
+    base = region.GetRegionBase()
+    end = region.GetRegionEnd()
 
+    if shrink:
+        addr2 = addr.GetValueAsUnsigned()
+        addr2 -= addr2 % 512
+        base = max(base, addr2 - 1024)
+        end = min(end, addr2 + 1024)
 
-def IsWithinRange(addr, range, target):
+    start = lldb.SBAddress(base, test_base.target)
+    size = end - base
+
+    return lldb.SBAddressRange(start, size)
+
+
+def IsWithinRange(addr, size, range, target):
     start_addr = range.GetBaseAddress().GetLoadAddress(target)
     end_addr = start_addr + range.GetByteSize()
     addr = addr.GetValueAsUnsigned()
-    return addr >= start_addr and addr < end_addr
+    return addr >= start_addr and addr + size <= end_addr
 
 
-def GetHeapRanges(test_base):
+def GetHeapRanges(test_base, shrink=False):
     frame = test_base.thread.GetSelectedFrame()
 
     ex = frame.EvaluateExpression("heap_pointer1")
     test_base.assertTrue(ex.IsValid())
-    range = GetRangeFromAddrValue(test_base, ex)
+    range = GetRangeFromAddrValue(test_base, ex, shrink)
     addr_ranges = lldb.SBAddressRangeList()
     addr_ranges.Append(range)
 
     ex = frame.EvaluateExpression("heap_pointer2")
     test_base.assertTrue(ex.IsValid())
-    if not IsWithinRange(ex, addr_ranges[0], test_base.target):
-        addr_ranges.Append(GetRangeFromAddrValue(test_base, ex))
+    size = len(DOUBLE_INSTANCE_PATTERN_HEAP)
+    if not IsWithinRange(ex, size, addr_ranges[0], test_base.target):
+        addr_ranges.Append(GetRangeFromAddrValue(test_base, ex, shrink))
 
     return addr_ranges
 
 
-def GetRanges(test_base):
-    ranges = GetHeapRanges(test_base)
-    ranges.Append(GetStackRanges(test_base))
+def GetRanges(test_base, shrink=False):
+    ranges = GetHeapRanges(test_base, shrink)
+    ranges.Append(GetStackRanges(test_base, shrink))
 
     return ranges

>From f0895aaf5b58cb43b76040b2ea200b5e274c25eb Mon Sep 17 00:00:00 2001
From: Igor Kudrin <ikudrin at accesssoftek.com>
Date: Sat, 12 Oct 2024 14:28:53 -0700
Subject: [PATCH 2/2] Rephrase the comment for GetRangeFromAddrValue

---
 .../API/python_api/find_in_memory/address_ranges_helper.py    | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lldb/test/API/python_api/find_in_memory/address_ranges_helper.py b/lldb/test/API/python_api/find_in_memory/address_ranges_helper.py
index ac8c6c9e15f1ca..dcceca6d8a5c5e 100644
--- a/lldb/test/API/python_api/find_in_memory/address_ranges_helper.py
+++ b/lldb/test/API/python_api/find_in_memory/address_ranges_helper.py
@@ -27,8 +27,8 @@ def GetStackRanges(test_base, shrink=False):
 
 
 def GetRangeFromAddrValue(test_base, addr, shrink=False):
-    """Return the address range containing 'addr'.
-    If 'shrink' is True, the size of the region will not exceed 2K.
+    """Returns a memory region containing 'addr'.
+    If 'shrink' is True, the address range will be reduced to not exceed 2K.
     """
     region = lldb.SBMemoryRegionInfo()
     test_base.assertTrue(



More information about the lldb-commits mailing list