Skip to content

Commit a537a48

Browse files
committed
[WIP] memory find speedup+bugfix
1 parent 20b2c9f commit a537a48

File tree

3 files changed

+108
-42
lines changed

3 files changed

+108
-42
lines changed

lldb/source/Target/Process.cpp

Lines changed: 24 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -114,33 +114,6 @@ class ProcessOptionValueProperties
114114
}
115115
};
116116

117-
class ProcessMemoryIterator {
118-
public:
119-
ProcessMemoryIterator(Process &process, lldb::addr_t base)
120-
: m_process(process), m_base_addr(base) {}
121-
122-
bool IsValid() { return m_is_valid; }
123-
124-
uint8_t operator[](lldb::addr_t offset) {
125-
if (!IsValid())
126-
return 0;
127-
128-
uint8_t retval = 0;
129-
Status error;
130-
if (0 == m_process.ReadMemory(m_base_addr + offset, &retval, 1, error)) {
131-
m_is_valid = false;
132-
return 0;
133-
}
134-
135-
return retval;
136-
}
137-
138-
private:
139-
Process &m_process;
140-
const lldb::addr_t m_base_addr;
141-
bool m_is_valid = true;
142-
};
143-
144117
static constexpr OptionEnumValueElement g_follow_fork_mode_values[] = {
145118
{
146119
eFollowParent,
@@ -3368,20 +3341,37 @@ lldb::addr_t Process::FindInMemory(lldb::addr_t low, lldb::addr_t high,
33683341
return LLDB_INVALID_ADDRESS;
33693342

33703343
std::vector<size_t> bad_char_heuristic(256, size);
3371-
ProcessMemoryIterator iterator(*this, low);
3372-
33733344
for (size_t idx = 0; idx < size - 1; idx++) {
33743345
decltype(bad_char_heuristic)::size_type bcu_idx = buf[idx];
33753346
bad_char_heuristic[bcu_idx] = size - idx - 1;
33763347
}
3377-
for (size_t s = 0; s <= (region_size - size);) {
3348+
3349+
llvm::SmallVector<uint8_t, 0> mem;
3350+
addr_t mem_pos = low;
3351+
const size_t read_size = std::max<size_t>(size, 0x10000);
3352+
3353+
for (addr_t s = low; s <= (high - size);) {
3354+
if (s + size >= mem.size() + mem_pos) {
3355+
mem.resize_for_overwrite(read_size);
3356+
Status error;
3357+
mem.resize(
3358+
ReadMemory(s, mem.data(), std::min(mem.size(), high - s), error));
3359+
mem_pos = s;
3360+
if (error.Fail()) {
3361+
MemoryRegionInfo info;
3362+
error = GetMemoryRegionInfo(s, info);
3363+
if (error.Fail())
3364+
return LLDB_INVALID_ADDRESS;
3365+
s = info.GetRange().GetRangeEnd();
3366+
continue;
3367+
}
3368+
}
33783369
int64_t j = size - 1;
3379-
while (j >= 0 && buf[j] == iterator[s + j])
3370+
while (j >= 0 && buf[j] == mem[s + j - mem_pos])
33803371
j--;
33813372
if (j < 0)
3382-
return low + s;
3383-
else
3384-
s += bad_char_heuristic[iterator[s + size - 1]];
3373+
return s;
3374+
s += bad_char_heuristic[mem[s + size - 1 - mem_pos]];
33853375
}
33863376

33873377
return LLDB_INVALID_ADDRESS;

lldb/test/API/functionalities/memory/find/TestMemoryFind.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,13 @@ def test_memory_find(self):
7979
'memory find -s "nothere" `stringdata` `stringdata+10`',
8080
substrs=["data not found within the range."],
8181
)
82+
83+
pagesize = self.frame().FindVariable("pagesize").GetValueAsUnsigned()
84+
mem_with_holes = self.frame().FindVariable("mem_with_holes").GetValueAsUnsigned()
85+
matches_var = self.frame().FindVariable("matches")
86+
self.assertEqual(matches_var.GetNumChildren(), 4)
87+
matches = [f'data found at location: {matches_var.GetChildAtIndex(i).GetValueAsUnsigned():#x}' for i in range(4)]
88+
self.expect(
89+
'memory find -c 5 -s "needle" `mem_with_holes` `mem_with_holes+5*pagesize`',
90+
substrs=matches + ["no more matches within the range"],
91+
)
Lines changed: 74 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,75 @@
1-
#include <stdio.h>
2-
#include <stdint.h>
3-
4-
int main (int argc, char const *argv[])
5-
{
6-
const char* stringdata = "hello world; I like to write text in const char pointers";
7-
uint8_t bytedata[] = {0xAA,0xBB,0xCC,0xDD,0xEE,0xFF,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99};
8-
return 0; // break here
1+
#include <cstdint>
2+
#include <cstdio>
3+
#include <cstdlib>
4+
#include <cstring>
5+
#include <initializer_list>
6+
7+
#ifdef _WIN32
8+
#include "Windows.h"
9+
10+
int getpagesize() {
11+
SYSTEM_INFO system_info;
12+
GetSystemInfo(&system_info);
13+
return system_info.dwPageSize;
14+
}
15+
16+
void *allocate_memory_with_holes() {
17+
int pagesize = getpagesize();
18+
void *mem = VirtualAlloc(nullptr, 5 * pagesize, MEM_RESERVE, PAGE_NOACCESS);
19+
if (!mem) {
20+
std::cerr << std::system_category().message(GetLastError()) << std::endl;
21+
exit(1);
22+
}
23+
char *bytes = static_cast<char *>(mem);
24+
for (int page : {0, 2, 4}) {
25+
if (!VirtualAlloc(bytes + page * pagesize, pagesize, MEM_COMMIT,
26+
PAGE_READWRITE)) {
27+
std::cerr << std::system_category().message(GetLastError()) << std::endl;
28+
exit(1);
29+
}
30+
}
31+
return bytes;
32+
}
33+
#else
34+
#include "sys/mman.h"
35+
#include "unistd.h"
36+
37+
char *allocate_memory_with_holes() {
38+
int pagesize = getpagesize();
39+
void *mem = mmap(nullptr, 5 * pagesize, PROT_READ | PROT_WRITE,
40+
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
41+
if (mem == MAP_FAILED) {
42+
perror("mmap");
43+
exit(1);
44+
}
45+
char *bytes = static_cast<char *>(mem);
46+
for (int page : {1, 3}) {
47+
if (munmap(bytes + page * pagesize, pagesize) != 0) {
48+
perror("munmap");
49+
exit(1);
50+
}
51+
}
52+
return bytes;
53+
}
54+
#endif
55+
56+
int main(int argc, char const *argv[]) {
57+
const char *stringdata =
58+
"hello world; I like to write text in const char pointers";
59+
uint8_t bytedata[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00, 0x11,
60+
0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99};
61+
62+
char *mem_with_holes = allocate_memory_with_holes();
63+
int pagesize = getpagesize();
64+
char *matches[] = {
65+
mem_with_holes, // Beginning of memory
66+
mem_with_holes + 2 * pagesize, // After a hole
67+
mem_with_holes + 2 * pagesize +
68+
pagesize / 2, // Middle of a block, after an existing match.
69+
mem_with_holes + 5 * pagesize - 7, // End of memory
70+
};
71+
for (char *m : matches)
72+
strcpy(m, "needle");
73+
74+
return 0; // break here
975
}

0 commit comments

Comments
 (0)