diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -1753,19 +1753,30 @@ if (!resolved_addr.IsValid()) resolved_addr = addr; - bool is_readonly = false; + // If we read from the file cache but can't get as many bytes as requested, + // we keep the result around in this buffer, in case this result is the + // best we can do. + std::unique_ptr file_cache_read_buffer; + size_t file_cache_bytes_read = 0; + // Read from file cache if read-only section. if (!force_live_memory && resolved_addr.IsSectionOffset()) { SectionSP section_sp(resolved_addr.GetSection()); if (section_sp) { auto permissions = Flags(section_sp->GetPermissions()); - is_readonly = !permissions.Test(ePermissionsWritable) && - permissions.Test(ePermissionsReadable); - } - if (is_readonly) { - bytes_read = ReadMemoryFromFileCache(resolved_addr, dst, dst_len, error); - if (bytes_read > 0) - return bytes_read; + bool is_readonly = !permissions.Test(ePermissionsWritable) && + permissions.Test(ePermissionsReadable); + if (is_readonly) { + file_cache_bytes_read = + ReadMemoryFromFileCache(resolved_addr, dst, dst_len, error); + if (file_cache_bytes_read == dst_len) + return file_cache_bytes_read; + else if (file_cache_bytes_read > 0) { + file_cache_read_buffer = + std::make_unique(file_cache_bytes_read); + std::memcpy(file_cache_read_buffer.get(), dst, file_cache_bytes_read); + } + } } } @@ -1804,7 +1815,14 @@ } } - if (!is_readonly && resolved_addr.IsSectionOffset()) { + if (file_cache_read_buffer.get() && file_cache_bytes_read > 0) { + // Reading from the process failed. If we've previously succeeded in reading + // something from the file cache, then copy that over and return that. + std::memcpy(dst, file_cache_read_buffer.get(), file_cache_bytes_read); + return file_cache_bytes_read; + } + + if (!file_cache_read_buffer.get() && resolved_addr.IsSectionOffset()) { // If we didn't already try and read from the object file cache, then try // it after failing to read from the process. return ReadMemoryFromFileCache(resolved_addr, dst, dst_len, error);