@@ -1974,25 +1974,36 @@ size_t Process::ReadMemory(addr_t addr, void *buf, size_t size, Status &error) {
19741974llvm::SmallVector<llvm::MutableArrayRef<uint8_t >>
19751975Process::ReadMemoryRanges (llvm::ArrayRef<Range<lldb::addr_t , size_t >> ranges,
19761976 llvm::MutableArrayRef<uint8_t > buffer) {
1977- llvm::SmallVector<llvm::MutableArrayRef<uint8_t >> results;
1977+ auto total_ranges_len = llvm::sum_of (
1978+ llvm::map_range (ranges, [](auto range) { return range.size ; }));
1979+ // If the buffer is not large enough, this is a programmer error.
1980+ // In production builds, gracefully fail by returning empty chunks.
1981+ assert (buffer.size () >= total_ranges_len);
1982+ if (buffer.size () < total_ranges_len)
1983+ return llvm::SmallVector<llvm::MutableArrayRef<uint8_t >>(ranges.size ());
19781984
1979- for (auto [addr, len] : ranges) {
1980- // This is either a programmer error, or a protocol violation.
1981- // In production builds, gracefully fail.
1982- assert (buffer.size () >= len);
1983- if (buffer.size () < len) {
1984- results.push_back (buffer.take_front (0 ));
1985- continue ;
1986- }
1985+ llvm::SmallVector<llvm::MutableArrayRef<uint8_t >> results;
19871986
1987+ // While `buffer` has space, take the next requested range and read
1988+ // memory into a `buffer` chunk, then slice it to remove the used chunk.
1989+ for (auto [addr, range_len] : ranges) {
19881990 Status status;
19891991 size_t num_bytes_read =
1990- ReadMemoryFromInferior (addr, buffer.data (), len , status);
1992+ ReadMemoryFromInferior (addr, buffer.data (), range_len , status);
19911993 // FIXME: ReadMemoryFromInferior promises to return 0 in case of errors, but
19921994 // it doesn't; it never checks for errors.
19931995 if (status.Fail ())
19941996 num_bytes_read = 0 ;
1997+
1998+ assert (num_bytes_read <= range_len && " read more than requested bytes" );
1999+ if (num_bytes_read > range_len) {
2000+ // In production builds, gracefully fail by returning an empty chunk.
2001+ results.emplace_back ();
2002+ continue ;
2003+ }
2004+
19952005 results.push_back (buffer.take_front (num_bytes_read));
2006+ // Slice buffer to remove the used chunk.
19962007 buffer = buffer.drop_front (num_bytes_read);
19972008 }
19982009
0 commit comments