Skip to content

Commit f65902a

Browse files
committed
[lldb][lldb-dap] Added support for "WriteMemory" request. #131820
Fixed review comments
2 parents 32f4823 + 683d775 commit f65902a

File tree

4 files changed

+36
-13
lines changed

4 files changed

+36
-13
lines changed

lldb/packages/Python/lldbsuite/test/tools/lldb-dap/dap_server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -734,7 +734,7 @@ def request_readMemory(self, memoryReference, offset, count):
734734
}
735735
return self.send_recv(command_dict)
736736

737-
def request_writeMemory(self, memoryReference, offset, data, allowPartial=True):
737+
def request_writeMemory(self, memoryReference, data, offset=0, allowPartial=True):
738738
args_dict = {
739739
"memoryReference": memoryReference,
740740
"offset": offset,

lldb/packages/Python/lldbsuite/test/tools/lldb-dap/lldbdap_testcase.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from lldbsuite.test.lldbtest import *
77
from lldbsuite.test import lldbplatformutil
88
import lldbgdbserverutils
9+
import base64
910

1011

1112
class DAPTestCaseBase(TestBase):
@@ -530,3 +531,11 @@ def getBuiltinDebugServerTool(self):
530531
self.dap_server.request_disconnect(terminateDebuggee=True)
531532
self.assertIsNotNone(server_tool, "debugserver not found.")
532533
return server_tool
534+
535+
def writeMemory(self, memoryReference, data=None, offset=None, allowPartial=None):
536+
# This function accepts data in decimal and hexadecimal format,
537+
# converts it to a Base64 string, and send it to the DAP,
538+
# which expects Base64 encoded data.
539+
encodedData = "" if data is None else base64.b64encode(data.to_bytes()).decode()
540+
response = self.dap_server.request_writeMemory(memoryReference, encodedData, offset=offset, allowPartial=allowPartial)
541+
return response

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

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ def test_writeMemory(self):
133133

134134
# Write the Base64-encoded string "Mg==", which decodes to binary 0x32
135135
# which is decimal 50 and corresponds to the ASCII character '2'.
136-
mem_response = self.dap_server.request_writeMemory(memref, 0, "Mg==")
136+
mem_response = self.writeMemory(memref, 50, 0, True)
137137
self.assertEqual(mem_response["success"], True)
138138
self.assertEqual(mem_response["body"]["bytesWritten"], 1)
139139

@@ -144,20 +144,28 @@ def test_writeMemory(self):
144144
self.assertEqual(mem_response["body"]["data"], "Mg==")
145145

146146
# Memory write failed for 0x0.
147-
mem_response = self.dap_server.request_writeMemory("0x0", 0, "Mg==")
147+
mem_response = self.writeMemory("0x0", 50, 0, True)
148148
self.assertEqual(mem_response["success"], False)
149149

150150
# Malformed memory reference.
151-
mem_response = self.dap_server.request_writeMemory("12345", 0, "Mg==")
151+
mem_response = self.writeMemory("12345", 50, 0, True)
152152
self.assertEqual(mem_response["success"], False)
153153

154154
ptr_deref = self.dap_server.request_evaluate("nonWritable")["body"]
155155
memref = ptr_deref["memoryReference"]
156156

157157
# Writing to non-writable region should return an appropriate error.
158-
mem_response = self.dap_server.request_writeMemory(memref, 0, "Mg==", False)
158+
mem_response = self.writeMemory(memref, 50, 0, False)
159159
self.assertEqual(mem_response["success"], False)
160160
self.assertRegex(
161161
mem_response["message"],
162-
r"Memory "+memref+" region is not writable",
162+
r"Memory " + memref + " region is not writable",
163+
)
164+
165+
# Trying to write empty value; data=""
166+
mem_response = self.writeMemory(memref)
167+
self.assertEqual(mem_response["success"], False)
168+
self.assertRegex(
169+
mem_response["message"],
170+
r"Data cannot be empty value. Provide valid data",
163171
)

lldb/tools/lldb-dap/Handler/WriteMemoryRequestHandler.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -113,23 +113,29 @@ void WriteMemoryRequestHandler::operator()(
113113
address + GetInteger<uint64_t>(arguments, "offset").value_or(0);
114114

115115
llvm::StringRef data64 = GetString(arguments, "data").value_or("");
116+
if (data64.empty()) {
117+
response["success"] = false;
118+
EmplaceSafeString(response, "message","Data cannot be empty value. Provide valid data");
119+
dap.SendJSON(llvm::json::Value(std::move(response)));
120+
return;
121+
}
116122

117123
// The VSCode IDE or other DAP clients send memory data as a Base64 string.
118124
// This function decodes it into raw binary before writing it to the target
119125
// process memory.
120126
std::vector<char> output;
121-
auto decodeError = llvm::decodeBase64(data64, output);
127+
auto decode_error = llvm::decodeBase64(data64, output);
122128

123-
if (decodeError) {
129+
if (decode_error) {
124130
response["success"] = false;
125-
EmplaceSafeString(response, "message",
126-
llvm::toString(std::move(decodeError)).c_str());
131+
EmpleceSafeErrorMessage(dap, response, "message",
132+
llvm::toString(std::move(decode_error)).c_str());
127133
dap.SendJSON(llvm::json::Value(std::move(response)));
128134
return;
129135
}
130136

131137
bool allowPartial = GetBoolean(arguments, "allowPartial").value_or(true);
132-
lldb::SBError writeError;
138+
lldb::SBError write_error;
133139
uint64_t bytes_written = 0;
134140

135141
// Write the memory
@@ -155,12 +161,12 @@ void WriteMemoryRequestHandler::operator()(
155161

156162
bytes_written =
157163
process.WriteMemory(address_offset, static_cast<void *>(output.data()),
158-
output.size(), writeError);
164+
output.size(), write_error);
159165
}
160166

161167
if (bytes_written == 0) {
162168
response["success"] = false;
163-
EmplaceSafeString(response, "message", writeError.GetCString());
169+
EmplaceSafeString(response, "message", write_error.GetCString());
164170
dap.SendJSON(llvm::json::Value(std::move(response)));
165171
return;
166172
}

0 commit comments

Comments
 (0)