[lldb] Speed up FindInMemory tests (#111951)

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.
This commit is contained in:
Igor Kudrin
2024-10-19 04:13:27 +07:00
committed by GitHub
parent 47d9ca87b0
commit b88d94caba
3 changed files with 45 additions and 31 deletions

View File

@@ -55,7 +55,7 @@ class FindInMemoryTestCase(TestBase):
error = lldb.SBError()
addr = self.process.FindInMemory(
SINGLE_INSTANCE_PATTERN_STACK,
GetStackRange(self),
GetStackRange(self, True),
1,
error,
)
@@ -70,7 +70,7 @@ class FindInMemoryTestCase(TestBase):
error = lldb.SBError()
addr = self.process.FindInMemory(
DOUBLE_INSTANCE_PATTERN_HEAP,
GetHeapRanges(self)[0],
GetHeapRanges(self, True)[0],
1,
error,
)
@@ -86,7 +86,7 @@ class FindInMemoryTestCase(TestBase):
error = lldb.SBError()
addr = self.process.FindInMemory(
SINGLE_INSTANCE_PATTERN_STACK,
GetStackRange(self),
GetStackRange(self, True),
0,
error,
)
@@ -118,7 +118,7 @@ class FindInMemoryTestCase(TestBase):
error = lldb.SBError()
addr = self.process.FindInMemory(
"",
GetStackRange(self),
GetStackRange(self, True),
1,
error,
)
@@ -131,7 +131,7 @@ class FindInMemoryTestCase(TestBase):
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(

View File

@@ -30,7 +30,7 @@ class FindRangesInMemoryTestCase(TestBase):
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 @@ class FindRangesInMemoryTestCase(TestBase):
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 @@ class FindRangesInMemoryTestCase(TestBase):
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 @@ class FindRangesInMemoryTestCase(TestBase):
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 @@ class FindRangesInMemoryTestCase(TestBase):
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 @@ class FindRangesInMemoryTestCase(TestBase):
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 @@ class FindRangesInMemoryTestCase(TestBase):
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 @@ class FindRangesInMemoryTestCase(TestBase):
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(

View File

@@ -6,27 +6,30 @@ ALIGNED_INSTANCE_PATTERN_HEAP = "i_am_unaligned_string_on_the_heap"
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):
"""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(
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)
start = lldb.SBAddress(base, test_base.target)
size = end - base
return lldb.SBAddressRange(start, size)
def IsWithinRange(addr, range, target):
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