Author: Felipe de Azevedo Piovezan Date: 2025-12-15T17:49:29Z New Revision: 566eb2b78ff0095cdd7cb7a793deb9c90b95124d
URL: https://github.com/llvm/llvm-project/commit/566eb2b78ff0095cdd7cb7a793deb9c90b95124d DIFF: https://github.com/llvm/llvm-project/commit/566eb2b78ff0095cdd7cb7a793deb9c90b95124d.diff LOG: [lldb] Respect max packet size limits for MultiMemRead in ProcessGDBRemote (#172022) (ignore the first commit, it is the dependency of this PR) Servers advertise what their maximum packet size is, MultiMemRead needs to respect that. Depends on: * https://github.com/llvm/llvm-project/pull/172020 Added: Modified: lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Removed: ################################################################################ diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index d1b0ead74701b..bae07245bdfa6 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -2790,6 +2790,29 @@ size_t ProcessGDBRemote::DoReadMemory(addr_t addr, void *buf, size_t size, return 0; } +/// Returns the number of ranges that is safe to request using MultiMemRead +/// while respecting max_packet_size. +static uint64_t ComputeNumRangesMultiMemRead( + uint64_t max_packet_size, + llvm::ArrayRef<Range<lldb::addr_t, size_t>> ranges) { + // Each range is specified by two numbers (up to 16 ASCII characters) and one + // comma. + constexpr uint64_t range_overhead = 33; + uint64_t current_size = 0; + for (auto [idx, range] : llvm::enumerate(ranges)) { + uint64_t potential_size = current_size + range.size + range_overhead; + if (potential_size > max_packet_size) { + if (idx == 0) + LLDB_LOG(GetLog(GDBRLog::Process), + "MultiMemRead input has a range (base = {0:x}, size = {1}) " + "bigger than the maximum allowed by remote", + range.base, range.size); + return idx; + } + } + return ranges.size(); +} + llvm::SmallVector<llvm::MutableArrayRef<uint8_t>> ProcessGDBRemote::ReadMemoryRanges( llvm::ArrayRef<Range<lldb::addr_t, size_t>> ranges, @@ -2797,22 +2820,34 @@ ProcessGDBRemote::ReadMemoryRanges( if (!m_gdb_comm.GetMultiMemReadSupported()) return Process::ReadMemoryRanges(ranges, buffer); - llvm::Expected<StringExtractorGDBRemote> response = - SendMultiMemReadPacket(ranges); - if (!response) { - LLDB_LOG_ERROR(GetLog(GDBRLog::Process), response.takeError(), - "MultiMemRead error response: {0}"); - return Process::ReadMemoryRanges(ranges, buffer); - } - - llvm::StringRef response_str = response->GetStringRef(); - const unsigned expected_num_ranges = ranges.size(); + const llvm::ArrayRef<Range<lldb::addr_t, size_t>> original_ranges = ranges; llvm::SmallVector<llvm::MutableArrayRef<uint8_t>> memory_regions; - if (llvm::Error error = ParseMultiMemReadPacket( - response_str, buffer, expected_num_ranges, memory_regions)) { - LLDB_LOG_ERROR(GetLog(GDBRLog::Process), std::move(error), - "MultiMemRead error parsing response: {0}"); - return Process::ReadMemoryRanges(ranges, buffer); + + while (!ranges.empty()) { + uint64_t num_ranges = + ComputeNumRangesMultiMemRead(m_max_memory_size, ranges); + if (num_ranges == 0) + return Process::ReadMemoryRanges(original_ranges, buffer); + + auto ranges_for_request = ranges.take_front(num_ranges); + ranges = ranges.drop_front(num_ranges); + + llvm::Expected<StringExtractorGDBRemote> response = + SendMultiMemReadPacket(ranges_for_request); + if (!response) { + LLDB_LOG_ERROR(GetLog(GDBRLog::Process), response.takeError(), + "MultiMemRead error response: {0}"); + return Process::ReadMemoryRanges(original_ranges, buffer); + } + + llvm::StringRef response_str = response->GetStringRef(); + const unsigned expected_num_ranges = ranges_for_request.size(); + if (llvm::Error error = ParseMultiMemReadPacket( + response_str, buffer, expected_num_ranges, memory_regions)) { + LLDB_LOG_ERROR(GetLog(GDBRLog::Process), std::move(error), + "MultiMemRead error parsing response: {0}"); + return Process::ReadMemoryRanges(original_ranges, buffer); + } } return memory_regions; } _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
