@@ -986,8 +986,13 @@ Status MinidumpFileBuilder::ReadWriteMemoryInChunks(
986986 *bytes_read = 0 ;
987987
988988 uint64_t bytes_remaining = size;
989+ // This is our flag to control if we had a partial read
990+ // if we read less than our expected number of bytes without
991+ // getting an error, we should add those bytes and discountine
992+ // trying to read.
993+ bool partialReadEncountered = false ;
989994 Status error;
990- while (bytes_remaining > 0 ) {
995+ while (bytes_remaining > 0 && !partialReadEncountered ) {
991996 // Get the next read chunk size as the minimum of the remaining bytes and
992997 // the write chunk max size.
993998 const size_t bytes_to_read =
@@ -1000,22 +1005,22 @@ Status MinidumpFileBuilder::ReadWriteMemoryInChunks(
10001005 " Failed to read memory region at: %" PRIx64
10011006 " . Bytes read: %zu, error: %s" ,
10021007 addr, bytes_read_for_chunk, error.AsCString ());
1003- // If we've read nothing, and get an error or fail to read
1004- // we can just give up early.
1005- if (*bytes_read == 0 )
1006- return Status ();
10071008
1008- // If we've read some bytes, we stop trying to read more and return
1009- // this best effort attempt
1010- bytes_remaining = 0 ;
1009+ // If we failed to read memory and got an error, we return and skip
1010+ // the rest of the region. We need to return a non-error status here
1011+ // because the caller can't differentiate between this skippable
1012+ // error, and an error appending data to the file, which is fatal.
1013+ return Status ();
10111014 } else if (bytes_read_for_chunk != bytes_to_read) {
1012- LLDB_LOGF (
1013- log, " Memory region at: %" PRIx64 " failed to read %" PRIx64 " bytes" ,
1014- addr, size);
1015+ LLDB_LOGF (log,
1016+ " Memory region at: %" PRIx64 " partiall read %" PRIx64
1017+ " bytes out of %" PRIx64 " bytes." ,
1018+ addr, bytes_read_for_chunk,
1019+ bytes_to_read - bytes_read_for_chunk);
10151020
10161021 // If we've read some bytes, we stop trying to read more and return
10171022 // this best effort attempt
1018- bytes_remaining = 0 ;
1023+ partialReadEncountered = true ;
10191024 }
10201025
10211026 // Write to the minidump file with the chunk potentially flushing to disk.
@@ -1026,20 +1031,15 @@ Status MinidumpFileBuilder::ReadWriteMemoryInChunks(
10261031 if (error.Fail ())
10271032 return error;
10281033
1029- // If the bytes read in this chunk would cause us to overflow, set the
1030- // remaining bytes to 0 so we exit. This is a safety check so we don't
1031- // get stuck building a bigger file forever.
1034+ // If the bytes read in this chunk would cause us to overflow, something
1035+ // went wrong and we should fail out of creating the Minidump.
10321036 if (bytes_read_for_chunk > bytes_remaining)
1033- bytes_remaining = 0 ;
1034-
1035- // This check is so we don't overflow when the error above sets the
1036- // bytes to read to 0 (the graceful exit condition).
1037- if (bytes_remaining > 0 )
1037+ return Status::FromErrorString (" Unexpected number of bytes read." );
1038+ else
10381039 bytes_remaining -= bytes_read_for_chunk;
10391040
1040- // If the caller wants a tally back of the bytes_read, update it as we
1041- // write. We do this in the loop so if we encounter an error we can
1042- // report the accurate total.
1041+ // Update the caller with the number of bytes read, but also written to the
1042+ // underlying buffer.
10431043 *bytes_read += bytes_read_for_chunk;
10441044 }
10451045
0 commit comments