Skip to content

Commit 372021f

Browse files
[lldb] Parse qSupported MultiMemRead tag in GDB Remote Client (llvm#163249)
This is in preparation for the new MultiMemRead packet discussed in the RFC [1]. An alternative to using `qSupported` would be having clients send an empty `MultiMemRead` packet. However, this is problematic because the already-existing packet `M` is a prefix of `MultiMemRead`; an empty reply would be ambiguous in this case. It is also risky that the stub might interpret the `MultiMemRead` as a valid `M` packet. Another advantage of `qSupported` is that this packet is already exchanged, so parsing a new field is simpler than having to exchange one extra packet. [1]: https://discourse.llvm.org/t/rfc-a-new-vectorized-memory-read-packet/88441 (cherry picked from commit ccf6e02)
1 parent 556e300 commit 372021f

File tree

3 files changed

+35
-0
lines changed

3 files changed

+35
-0
lines changed

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,12 @@ bool GDBRemoteCommunicationClient::GetReverseStepSupported() {
211211
return m_supports_reverse_step == eLazyBoolYes;
212212
}
213213

214+
bool GDBRemoteCommunicationClient::GetMultiMemReadSupported() {
215+
if (m_supports_multi_mem_read == eLazyBoolCalculate)
216+
GetRemoteQSupported();
217+
return m_supports_multi_mem_read == eLazyBoolYes;
218+
}
219+
214220
bool GDBRemoteCommunicationClient::QueryNoAckModeSupported() {
215221
if (m_supports_not_sending_acks == eLazyBoolCalculate) {
216222
m_send_acks = true;
@@ -339,6 +345,7 @@ void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) {
339345
m_supported_async_json_packets_is_valid = false;
340346
m_supported_async_json_packets_sp.reset();
341347
m_supports_jModulesInfo = true;
348+
m_supports_multi_mem_read = eLazyBoolCalculate;
342349
}
343350

344351
// These flags should be reset when we first connect to a GDB server and when
@@ -365,6 +372,7 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
365372
m_x_packet_state.reset();
366373
m_supports_reverse_continue = eLazyBoolNo;
367374
m_supports_reverse_step = eLazyBoolNo;
375+
m_supports_multi_mem_read = eLazyBoolNo;
368376

369377
m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if
370378
// not, we assume no limit
@@ -424,6 +432,8 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
424432
m_supports_reverse_continue = eLazyBoolYes;
425433
else if (x == "ReverseStep+")
426434
m_supports_reverse_step = eLazyBoolYes;
435+
else if (x == "MultiMemRead+")
436+
m_supports_multi_mem_read = eLazyBoolYes;
427437
// Look for a list of compressions in the features list e.g.
428438
// qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-
429439
// deflate,lzma

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,8 @@ class GDBRemoteCommunicationClient : public GDBRemoteClientBase {
342342

343343
bool GetReverseStepSupported();
344344

345+
bool GetMultiMemReadSupported();
346+
345347
LazyBool SupportsAllocDeallocMemory() // const
346348
{
347349
// Uncomment this to have lldb pretend the debug server doesn't respond to
@@ -574,6 +576,7 @@ class GDBRemoteCommunicationClient : public GDBRemoteClientBase {
574576
std::optional<xPacketState> m_x_packet_state;
575577
LazyBool m_supports_reverse_continue = eLazyBoolCalculate;
576578
LazyBool m_supports_reverse_step = eLazyBoolCalculate;
579+
LazyBool m_supports_multi_mem_read = eLazyBoolCalculate;
577580

578581
bool m_supports_qProcessInfoPID : 1, m_supports_qfProcessInfo : 1,
579582
m_supports_qUserName : 1, m_supports_qGroupName : 1,

lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,3 +639,25 @@ TEST_F(GDBRemoteCommunicationClientTest, CalculateMD5) {
639639
EXPECT_EQ(expected_high, result->high());
640640
}
641641
#endif
642+
643+
TEST_F(GDBRemoteCommunicationClientTest, MultiMemReadSupported) {
644+
std::future<bool> async_result = std::async(std::launch::async, [&] {
645+
StringExtractorGDBRemote qSupported_packet_request;
646+
server.GetPacket(qSupported_packet_request);
647+
server.SendPacket("MultiMemRead+;");
648+
return true;
649+
});
650+
ASSERT_TRUE(client.GetMultiMemReadSupported());
651+
async_result.wait();
652+
}
653+
654+
TEST_F(GDBRemoteCommunicationClientTest, MultiMemReadNotSupported) {
655+
std::future<bool> async_result = std::async(std::launch::async, [&] {
656+
StringExtractorGDBRemote qSupported_packet_request;
657+
server.GetPacket(qSupported_packet_request);
658+
server.SendPacket(";");
659+
return true;
660+
});
661+
ASSERT_FALSE(client.GetMultiMemReadSupported());
662+
async_result.wait();
663+
}

0 commit comments

Comments
 (0)