Skip to content

Commit fc60825

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 61a73a7 commit fc60825

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
@@ -198,6 +198,12 @@ uint64_t GDBRemoteCommunicationClient::GetRemoteMaxPacketSize() {
198198
return m_max_packet_size;
199199
}
200200

201+
bool GDBRemoteCommunicationClient::GetMultiMemReadSupported() {
202+
if (m_supports_multi_mem_read == eLazyBoolCalculate)
203+
GetRemoteQSupported();
204+
return m_supports_multi_mem_read == eLazyBoolYes;
205+
}
206+
201207
bool GDBRemoteCommunicationClient::QueryNoAckModeSupported() {
202208
if (m_supports_not_sending_acks == eLazyBoolCalculate) {
203209
m_send_acks = true;
@@ -324,6 +330,7 @@ void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) {
324330
m_supported_async_json_packets_is_valid = false;
325331
m_supported_async_json_packets_sp.reset();
326332
m_supports_jModulesInfo = true;
333+
m_supports_multi_mem_read = eLazyBoolCalculate;
327334
}
328335

329336
// These flags should be reset when we first connect to a GDB server and when
@@ -347,6 +354,7 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
347354
m_supports_memory_tagging = eLazyBoolNo;
348355
m_supports_qSaveCore = eLazyBoolNo;
349356
m_uses_native_signals = eLazyBoolNo;
357+
m_supports_multi_mem_read = eLazyBoolNo;
350358

351359
m_max_packet_size = UINT64_MAX; // It's supposed to always be there, but if
352360
// not, we assume no limit
@@ -397,6 +405,8 @@ void GDBRemoteCommunicationClient::GetRemoteQSupported() {
397405
m_supports_qSaveCore = eLazyBoolYes;
398406
else if (x == "native-signals+")
399407
m_uses_native_signals = eLazyBoolYes;
408+
else if (x == "MultiMemRead+")
409+
m_supports_multi_mem_read = eLazyBoolYes;
400410
// Look for a list of compressions in the features list e.g.
401411
// qXfer:features:read+;PacketSize=20000;qEcho+;SupportedCompressions=zlib-
402412
// deflate,lzma

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

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

332332
bool GetMultiprocessSupported();
333333

334+
bool GetMultiMemReadSupported();
335+
334336
LazyBool SupportsAllocDeallocMemory() // const
335337
{
336338
// Uncomment this to have lldb pretend the debug server doesn't respond to
@@ -561,6 +563,7 @@ class GDBRemoteCommunicationClient : public GDBRemoteClientBase {
561563
LazyBool m_supports_memory_tagging = eLazyBoolCalculate;
562564
LazyBool m_supports_qSaveCore = eLazyBoolCalculate;
563565
LazyBool m_uses_native_signals = eLazyBoolCalculate;
566+
LazyBool m_supports_multi_mem_read = eLazyBoolCalculate;
564567

565568
bool m_supports_qProcessInfoPID : 1, m_supports_qfProcessInfo : 1,
566569
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
@@ -631,3 +631,25 @@ TEST_F(GDBRemoteCommunicationClientTest, CalculateMD5) {
631631
EXPECT_EQ(expected_high, result->high());
632632
}
633633
#endif
634+
635+
TEST_F(GDBRemoteCommunicationClientTest, MultiMemReadSupported) {
636+
std::future<bool> async_result = std::async(std::launch::async, [&] {
637+
StringExtractorGDBRemote qSupported_packet_request;
638+
server.GetPacket(qSupported_packet_request);
639+
server.SendPacket("MultiMemRead+;");
640+
return true;
641+
});
642+
ASSERT_TRUE(client.GetMultiMemReadSupported());
643+
async_result.wait();
644+
}
645+
646+
TEST_F(GDBRemoteCommunicationClientTest, MultiMemReadNotSupported) {
647+
std::future<bool> async_result = std::async(std::launch::async, [&] {
648+
StringExtractorGDBRemote qSupported_packet_request;
649+
server.GetPacket(qSupported_packet_request);
650+
server.SendPacket(";");
651+
return true;
652+
});
653+
ASSERT_FALSE(client.GetMultiMemReadSupported());
654+
async_result.wait();
655+
}

0 commit comments

Comments
 (0)