Skip to content

Commit 3d54853

Browse files
committed
[lldb-dap] Allow empty memory reference in disassemble arguments
1 parent 675be0d commit 3d54853

File tree

5 files changed

+38
-3
lines changed

5 files changed

+38
-3
lines changed

lldb/test/API/tools/lldb-dap/disassemble/TestDAP_disassemble.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,25 @@ def test_disassemble_backwards(self):
9191
# clear breakpoints
9292
self.set_source_breakpoints(source, [])
9393
self.continue_to_exit()
94+
95+
def test_disassemble_empty_memory_reference(self):
96+
"""
97+
Tests the 'disassemble' request with empty memory reference.
98+
"""
99+
program = self.getBuildArtifact("a.out")
100+
self.build_and_launch(program)
101+
source = "main.c"
102+
bp_line_no = line_number(source, "// breakpoint 1")
103+
self.set_source_breakpoints(source, [bp_line_no])
104+
self.continue_to_next_stop()
105+
106+
instructions = self.dap_server.request_disassemble(
107+
memoryReference="", instructionOffset=0, instructionCount=50
108+
)
109+
self.assertEqual(len(instructions), 50)
110+
for instruction in instructions:
111+
self.assertEqual(instruction["presentationHint"], "invalid")
112+
113+
# clear breakpoints
114+
self.set_source_breakpoints(source, [])
115+
self.continue_to_exit()

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,11 @@ static DisassembledInstruction ConvertSBInstructionToDisassembledInstruction(
182182
/// `supportsDisassembleRequest` is true.
183183
llvm::Expected<DisassembleResponseBody>
184184
DisassembleRequestHandler::Run(const DisassembleArguments &args) const {
185+
if (args.memoryReference == LLDB_INVALID_ADDRESS) {
186+
std::vector<DisassembledInstruction> invalid_instructions(
187+
args.instructionCount, GetInvalidInstruction());
188+
return DisassembleResponseBody{std::move(invalid_instructions)};
189+
}
185190
const lldb::addr_t addr_ptr = args.memoryReference + args.offset;
186191
lldb::SBAddress addr(addr_ptr, dap.target);
187192
if (!addr.IsValid())

lldb/tools/lldb-dap/JSONUtils.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ DecodeMemoryReference(llvm::StringRef memoryReference) {
122122

123123
bool DecodeMemoryReference(const llvm::json::Value &v, llvm::StringLiteral key,
124124
lldb::addr_t &out, llvm::json::Path path,
125-
bool required) {
125+
bool required, bool allow_empty) {
126126
const llvm::json::Object *v_obj = v.getAsObject();
127127
if (!v_obj) {
128128
path.report("expected object");
@@ -145,6 +145,11 @@ bool DecodeMemoryReference(const llvm::json::Value &v, llvm::StringLiteral key,
145145
return false;
146146
}
147147

148+
if (allow_empty && mem_ref_str->empty()) {
149+
out = LLDB_INVALID_ADDRESS;
150+
return true;
151+
}
152+
148153
const std::optional<lldb::addr_t> addr_opt =
149154
DecodeMemoryReference(*mem_ref_str);
150155
if (!addr_opt) {

lldb/tools/lldb-dap/JSONUtils.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,11 +156,14 @@ DecodeMemoryReference(llvm::StringRef memoryReference);
156156
/// Indicates if the key is required to be present, otherwise report an error
157157
/// if the key is missing.
158158
///
159+
/// \param[in] allow_empty
160+
/// Interpret empty string as a valid value, don't report an error.
161+
///
159162
/// \return
160163
/// Returns \b true if the address was decoded successfully.
161164
bool DecodeMemoryReference(const llvm::json::Value &v, llvm::StringLiteral key,
162165
lldb::addr_t &out, llvm::json::Path path,
163-
bool required);
166+
bool required, bool allow_empty = false);
164167

165168
/// Extract an array of strings for the specified key from an object.
166169
///

lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,7 @@ bool fromJSON(const llvm::json::Value &Params, DisassembleArguments &DA,
511511
json::ObjectMapper O(Params, P);
512512
return O &&
513513
DecodeMemoryReference(Params, "memoryReference", DA.memoryReference, P,
514-
/*required=*/true) &&
514+
/*required=*/true, /*allow_empty*/ true) &&
515515
O.mapOptional("offset", DA.offset) &&
516516
O.mapOptional("instructionOffset", DA.instructionOffset) &&
517517
O.map("instructionCount", DA.instructionCount) &&

0 commit comments

Comments
 (0)