@@ -986,8 +986,13 @@ Status MinidumpFileBuilder::ReadWriteMemoryInChunks(
986
986
*bytes_read = 0 ;
987
987
988
988
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 ;
989
994
Status error;
990
- while (bytes_remaining > 0 ) {
995
+ while (bytes_remaining > 0 && !partialReadEncountered ) {
991
996
// Get the next read chunk size as the minimum of the remaining bytes and
992
997
// the write chunk max size.
993
998
const size_t bytes_to_read =
@@ -1000,22 +1005,22 @@ Status MinidumpFileBuilder::ReadWriteMemoryInChunks(
1000
1005
" Failed to read memory region at: %" PRIx64
1001
1006
" . Bytes read: %zu, error: %s" ,
1002
1007
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 ();
1007
1008
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 ();
1011
1014
} 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);
1015
1020
1016
1021
// If we've read some bytes, we stop trying to read more and return
1017
1022
// this best effort attempt
1018
- bytes_remaining = 0 ;
1023
+ partialReadEncountered = true ;
1019
1024
}
1020
1025
1021
1026
// Write to the minidump file with the chunk potentially flushing to disk.
@@ -1026,20 +1031,15 @@ Status MinidumpFileBuilder::ReadWriteMemoryInChunks(
1026
1031
if (error.Fail ())
1027
1032
return error;
1028
1033
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.
1032
1036
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
1038
1039
bytes_remaining -= bytes_read_for_chunk;
1039
1040
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.
1043
1043
*bytes_read += bytes_read_for_chunk;
1044
1044
}
1045
1045
0 commit comments