Skip to content

Commit 04ed12c

Browse files
authored
[lldb] Support partial memory reads on windows (#106981)
ReadProcessMemory will not perform the read if part of the memory is unreadable (and even though the API has a `number_of_bytes_read` argument). To make this work, I explicitly inspect the memory region being read and only read the accessible part.
1 parent 525ffd6 commit 04ed12c

File tree

2 files changed

+19
-7
lines changed

2 files changed

+19
-7
lines changed

lldb/source/Plugins/Process/Windows/Common/ProcessDebugger.cpp

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -276,16 +276,29 @@ Status ProcessDebugger::ReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
276276
LLDB_LOG(log, "attempting to read {0} bytes from address {1:x}", size,
277277
vm_addr);
278278

279-
HostProcess process = m_session_data->m_debugger->GetProcess();
279+
lldb::process_t handle = m_session_data->m_debugger->GetProcess()
280+
.GetNativeProcess()
281+
.GetSystemHandle();
280282
void *addr = reinterpret_cast<void *>(vm_addr);
281283
SIZE_T num_of_bytes_read = 0;
282-
if (!::ReadProcessMemory(process.GetNativeProcess().GetSystemHandle(), addr,
283-
buf, size, &num_of_bytes_read)) {
284-
error = Status(GetLastError(), eErrorTypeWin32);
285-
LLDB_LOG(log, "reading failed with error: {0}", error);
286-
} else {
284+
if (::ReadProcessMemory(handle, addr, buf, size, &num_of_bytes_read)) {
285+
bytes_read = num_of_bytes_read;
286+
return Status();
287+
}
288+
error = Status(GetLastError(), eErrorTypeWin32);
289+
MemoryRegionInfo info;
290+
if (GetMemoryRegionInfo(vm_addr, info).Fail() ||
291+
info.GetMapped() != MemoryRegionInfo::OptionalBool::eYes)
292+
return error;
293+
size = info.GetRange().GetRangeEnd() - vm_addr;
294+
LLDB_LOG(log, "retrying the read with size {0:x}", size);
295+
if (::ReadProcessMemory(handle, addr, buf, size, &num_of_bytes_read)) {
296+
LLDB_LOG(log, "success: read {0:x} bytes", num_of_bytes_read);
287297
bytes_read = num_of_bytes_read;
298+
return Status();
288299
}
300+
error = Status(GetLastError(), eErrorTypeWin32);
301+
LLDB_LOG(log, "error: {0}", error);
289302
return error;
290303
}
291304

lldb/test/API/functionalities/memory/holes/TestMemoryHoles.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ def _prepare_inferior(self):
5050
]
5151
self.assertEqual(len(self.positions), 5)
5252

53-
@expectedFailureWindows
5453
def test_memory_read(self):
5554
self._prepare_inferior()
5655

0 commit comments

Comments
 (0)