Skip to content

Commit b8d2671

Browse files
vogelsgesangJDevlieghere
authored andcommitted
[lldb-dap] Simplify readMemory (llvm#109485)
The `readMemory` request used the `MemoryRegionInfo` so it could also support short reads. Since llvm#106532, this is no longer necessary, as mentioned by @labath in a comment on llvm#104317. With this commit, we no longer set the `unreadableBytes` in the result. But this is optional, anyway, according to the spec, and afaik the VS Code UI does not make good use of `unreadableBytes`, anyway. We prefer `SBTarget::ReadMemory` over `SBProcess::ReadMemory`, because the `memory read` command also reads memory through the target instead of the process, and because users would expect the UI view and the results from memory read to be in-sync. (cherry picked from commit 786dc5a)
1 parent ad1445d commit b8d2671

File tree

2 files changed

+23
-54
lines changed

2 files changed

+23
-54
lines changed

lldb/test/API/tools/lldb-dap/memory/TestDAP_memory.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,12 @@ def test_readMemory(self):
9393

9494
# We can read the complete string
9595
mem = self.dap_server.request_readMemory(memref, 0, 5)["body"]
96-
self.assertEqual(mem["unreadableBytes"], 0)
9796
self.assertEqual(b64decode(mem["data"]), b"dead\0")
9897

98+
# We can read large chunks, potentially returning partial results
99+
mem = self.dap_server.request_readMemory(memref, 0, 4096)["body"]
100+
self.assertEqual(b64decode(mem["data"])[0:5], b"dead\0")
101+
99102
# Use an offset
100103
mem = self.dap_server.request_readMemory(memref, 2, 3)["body"]
101104
self.assertEqual(b64decode(mem["data"]), b"ad\0")
@@ -105,12 +108,11 @@ def test_readMemory(self):
105108
self.assertEqual(b64decode(mem["data"])[1:], b"dead\0")
106109

107110
# Reads of size 0 are successful
108-
# VS-Code sends those in order to check if a `memoryReference` can actually be dereferenced.
111+
# VS Code sends those in order to check if a `memoryReference` can actually be dereferenced.
109112
mem = self.dap_server.request_readMemory(memref, 0, 0)
110113
self.assertEqual(mem["success"], True)
111114
self.assertEqual(mem["body"]["data"], "")
112115

113116
# Reads at offset 0x0 fail
114117
mem = self.dap_server.request_readMemory("0x0", 0, 6)
115118
self.assertEqual(mem["success"], False)
116-
self.assertEqual(mem["message"], "Memory region is not readable")

lldb/tools/lldb-dap/lldb-dap.cpp

Lines changed: 18 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -4425,14 +4425,6 @@ void request_readMemory(const llvm::json::Object &request) {
44254425
FillResponse(request, response);
44264426
auto *arguments = request.getObject("arguments");
44274427

4428-
lldb::SBProcess process = g_dap.target.GetProcess();
4429-
if (!process.IsValid()) {
4430-
response["success"] = false;
4431-
response["message"] = "No process running";
4432-
g_dap.SendJSON(llvm::json::Value(std::move(response)));
4433-
return;
4434-
}
4435-
44364428
llvm::StringRef memoryReference = GetString(arguments, "memoryReference");
44374429
auto addr_opt = DecodeMemoryReference(memoryReference);
44384430
if (!addr_opt.has_value()) {
@@ -4442,57 +4434,32 @@ void request_readMemory(const llvm::json::Object &request) {
44424434
g_dap.SendJSON(llvm::json::Value(std::move(response)));
44434435
return;
44444436
}
4445-
lldb::addr_t addr = *addr_opt;
4446-
4447-
addr += GetSigned(arguments, "offset", 0);
4448-
const uint64_t requested_count = GetUnsigned(arguments, "count", 0);
4449-
lldb::SBMemoryRegionInfo region_info;
4450-
lldb::SBError memreg_error = process.GetMemoryRegionInfo(addr, region_info);
4451-
if (memreg_error.Fail()) {
4452-
response["success"] = false;
4453-
EmplaceSafeString(response, "message",
4454-
"Unable to find memory region: " +
4455-
std::string(memreg_error.GetCString()));
4456-
g_dap.SendJSON(llvm::json::Value(std::move(response)));
4457-
return;
4458-
}
4459-
if (!region_info.IsReadable()) {
4437+
lldb::addr_t addr_int = *addr_opt;
4438+
addr_int += GetSigned(arguments, "offset", 0);
4439+
const uint64_t count_requested = GetUnsigned(arguments, "count", 0);
4440+
4441+
// We also need support reading 0 bytes
4442+
// VS Code sends those requests to check if a `memoryReference`
4443+
// can be dereferenced.
4444+
const uint64_t count_read = std::max<uint64_t>(count_requested, 1);
4445+
std::vector<uint8_t> buf;
4446+
buf.resize(count_read);
4447+
lldb::SBError error;
4448+
lldb::SBAddress addr{addr_int, g_dap.target};
4449+
size_t count_result =
4450+
g_dap.target.ReadMemory(addr, buf.data(), count_read, error);
4451+
if (count_result == 0) {
44604452
response["success"] = false;
4461-
response.try_emplace("message", "Memory region is not readable");
4453+
EmplaceSafeString(response, "message", error.GetCString());
44624454
g_dap.SendJSON(llvm::json::Value(std::move(response)));
44634455
return;
44644456
}
4465-
const uint64_t available_count =
4466-
std::min(requested_count, region_info.GetRegionEnd() - addr);
4467-
const uint64_t unavailable_count = requested_count - available_count;
4468-
4469-
std::vector<uint8_t> buf;
4470-
buf.resize(available_count);
4471-
if (available_count > 0) {
4472-
lldb::SBError memread_error;
4473-
uint64_t bytes_read =
4474-
process.ReadMemory(addr, buf.data(), available_count, memread_error);
4475-
if (memread_error.Fail()) {
4476-
response["success"] = false;
4477-
EmplaceSafeString(response, "message",
4478-
"Unable to read memory: " +
4479-
std::string(memread_error.GetCString()));
4480-
g_dap.SendJSON(llvm::json::Value(std::move(response)));
4481-
return;
4482-
}
4483-
if (bytes_read != available_count) {
4484-
response["success"] = false;
4485-
EmplaceSafeString(response, "message", "Unexpected, short read");
4486-
g_dap.SendJSON(llvm::json::Value(std::move(response)));
4487-
return;
4488-
}
4489-
}
4457+
buf.resize(std::min(count_result, count_requested));
44904458

44914459
llvm::json::Object body;
4492-
std::string formatted_addr = "0x" + llvm::utohexstr(addr);
4460+
std::string formatted_addr = "0x" + llvm::utohexstr(addr_int);
44934461
body.try_emplace("address", formatted_addr);
44944462
body.try_emplace("data", llvm::encodeBase64(buf));
4495-
body.try_emplace("unreadableBytes", unavailable_count);
44964463
response.try_emplace("body", std::move(body));
44974464
g_dap.SendJSON(llvm::json::Value(std::move(response)));
44984465
}

0 commit comments

Comments
 (0)