Skip to content

Commit 3561fc7

Browse files
[lldb-server] Implement support for MultiBreakpoint packet
This is fairly straightforward, thanks to the helper functions created in the previous commit. #192910
1 parent 86cf048 commit 3561fc7

6 files changed

Lines changed: 69 additions & 1 deletion

File tree

lldb/include/lldb/Utility/StringExtractorGDBRemote.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ class StringExtractorGDBRemote : public StringExtractor {
172172
eServerPacketType_jLLDBTraceStop,
173173
eServerPacketType_jLLDBTraceGetState,
174174
eServerPacketType_jLLDBTraceGetBinaryData,
175+
eServerPacketType_jMultiBreakpoint,
175176

176177
eServerPacketType_qMemTags, // read memory tags
177178
eServerPacketType_QMemTags, // write memory tags

lldb/packages/Python/lldbsuite/test/tools/lldb-server/gdbremote_testcase.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -932,6 +932,7 @@ def add_qSupported_packets(self, client_features=[]):
932932
"SupportedWatchpointTypes",
933933
"SupportedCompressions",
934934
"MultiMemRead",
935+
"jMultiBreakpoint",
935936
]
936937

937938
def parse_qSupported_response(self, context):

lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,9 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() {
217217
RegisterMemberFunctionHandler(
218218
StringExtractorGDBRemote::eServerPacketType_jLLDBTraceGetBinaryData,
219219
&GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceGetBinaryData);
220+
RegisterMemberFunctionHandler(
221+
StringExtractorGDBRemote::eServerPacketType_jMultiBreakpoint,
222+
&GDBRemoteCommunicationServerLLGS::Handle_jMultiBreakpoint);
220223

221224
RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_g,
222225
&GDBRemoteCommunicationServerLLGS::Handle_g);
@@ -3123,6 +3126,65 @@ GDBRemoteCommunicationServerLLGS::Handle_z(StringExtractorGDBRemote &packet) {
31233126
ExecuteRemoveBreakpoint(packet.GetStringRef()));
31243127
}
31253128

3129+
GDBRemoteCommunication::PacketResult
3130+
GDBRemoteCommunicationServerLLGS::Handle_jMultiBreakpoint(
3131+
StringExtractorGDBRemote &packet) {
3132+
llvm::StringRef packet_str = packet.GetStringRef();
3133+
if (!packet_str.consume_front("jMultiBreakpoint:"))
3134+
return SendIllFormedResponse(packet,
3135+
"Invalid jMultiBreakpoint packet prefix");
3136+
3137+
llvm::Expected<llvm::json::Value> parsed = llvm::json::parse(packet_str);
3138+
if (!parsed) {
3139+
llvm::consumeError(parsed.takeError());
3140+
return SendIllFormedResponse(
3141+
packet, "jMultiBreakpoint did not contain a JSON dictionary");
3142+
}
3143+
llvm::json::Object *request_dict = parsed->getAsObject();
3144+
if (!request_dict)
3145+
return SendIllFormedResponse(
3146+
packet, "jMultiBreakpoint did not contain a JSON dictionary");
3147+
3148+
llvm::json::Array *request_array =
3149+
request_dict->getArray("breakpoint_requests");
3150+
if (!request_array)
3151+
return SendIllFormedResponse(
3152+
packet,
3153+
"jMultiBreakpoint did not contain a valid 'breakpoint_requests' field");
3154+
3155+
llvm::json::Array reply_array;
3156+
for (const llvm::json::Value &value : *request_array) {
3157+
std::optional<llvm::StringRef> request = value.getAsString();
3158+
if (!request)
3159+
return SendIllFormedResponse(packet,
3160+
"jMultiBreakpoint had a non-string entry");
3161+
BreakpointResult result = request->starts_with("Z")
3162+
? ExecuteSetBreakpoint(*request)
3163+
: ExecuteRemoveBreakpoint(*request);
3164+
switch (result.kind) {
3165+
case BreakpointResult::Kind::OK:
3166+
reply_array.push_back("OK");
3167+
break;
3168+
case BreakpointResult::Kind::Error:
3169+
reply_array.push_back(llvm::formatv("E{0:X-2}", result.error_code).str());
3170+
break;
3171+
case BreakpointResult::Kind::IllFormed:
3172+
reply_array.push_back("E03");
3173+
break;
3174+
}
3175+
}
3176+
3177+
llvm::json::Object dict;
3178+
dict.try_emplace("results", std::move(reply_array));
3179+
3180+
StreamString stream;
3181+
stream.AsRawOstream() << llvm::json::Value(std::move(reply_array));
3182+
StringRef response_str = stream.GetString();
3183+
StreamGDBRemote response;
3184+
response.PutEscapedBytes(response_str.data(), response_str.size());
3185+
return SendPacketNoLock(response.GetString());
3186+
}
3187+
31263188
GDBRemoteCommunication::PacketResult
31273189
GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) {
31283190
Log *log = GetLog(LLDBLog::Process | LLDBLog::Thread);
@@ -4338,6 +4400,7 @@ std::vector<std::string> GDBRemoteCommunicationServerLLGS::HandleFeatures(
43384400
"QListThreadsInStopReply+",
43394401
"qXfer:features:read+",
43404402
"QNonStop+",
4403+
"jMultiBreakpoint+",
43414404
});
43424405

43434406
// report server-only features

lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,8 @@ class GDBRemoteCommunicationServerLLGS
276276

277277
PacketResult Handle_T(StringExtractorGDBRemote &packet);
278278

279+
PacketResult Handle_jMultiBreakpoint(StringExtractorGDBRemote &packet);
280+
279281
void SetCurrentThreadID(lldb::tid_t tid);
280282

281283
lldb::tid_t GetCurrentThreadID() const;

lldb/source/Utility/StringExtractorGDBRemote.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,8 @@ StringExtractorGDBRemote::GetServerPacketType() const {
330330
return eServerPacketType_jLLDBTraceGetState;
331331
if (PACKET_STARTS_WITH("jLLDBTraceGetBinaryData:"))
332332
return eServerPacketType_jLLDBTraceGetBinaryData;
333+
if (PACKET_STARTS_WITH("jMultiBreakpoint:"))
334+
return eServerPacketType_jMultiBreakpoint;
333335
break;
334336

335337
case 'v':

lldb/test/API/functionalities/multi-breakpoint/TestMultiBreakpoint.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
from lldbsuite.test import lldbutil
1212

1313

14-
@skipUnlessDarwin # Remove once lldbsever support is implemented.
1514
@skipIfOutOfTreeDebugserver
1615
class TestMultiBreakpoint(TestBase):
1716
def send_packet(self, packet_str):

0 commit comments

Comments
 (0)