@@ -970,64 +970,44 @@ Status MinidumpFileBuilder::DumpDirectories() const {
970
970
}
971
971
972
972
Status MinidumpFileBuilder::ReadWriteMemoryInChunks (
973
- const std::unique_ptr<lldb_private::DataBufferHeap> &data_up,
974
- const lldb_private::CoreFileMemoryRange &range, uint64_t *bytes_read) {
975
- if (!data_up)
976
- return Status::FromErrorString (" No buffer supplied to read memory." );
973
+ lldb_private::DataBufferHeap &data_buffer,
974
+ const lldb_private::CoreFileMemoryRange &range, uint64_t &bytes_read) {
977
975
978
- if (!bytes_read)
979
- return Status::FromErrorString (" Bytes read pointer cannot be null." );
980
976
Log *log = GetLog (LLDBLog::Object);
981
977
const lldb::addr_t addr = range.range .start ();
982
978
const lldb::addr_t size = range.range .size ();
983
- // First we set the byte tally to 0, so if we do exit gracefully
984
- // the caller doesn't think the random garbage on the stack is a
985
- // success.
986
- *bytes_read = 0 ;
987
979
988
980
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 ;
994
981
Status error;
995
- while (bytes_remaining > 0 && !partialReadEncountered ) {
982
+ while (bytes_remaining > 0 ) {
996
983
// Get the next read chunk size as the minimum of the remaining bytes and
997
984
// the write chunk max size.
998
985
const size_t bytes_to_read =
999
- std::min (bytes_remaining, data_up-> GetByteSize ());
986
+ std::min (bytes_remaining, data_buffer. GetByteSize ());
1000
987
const size_t bytes_read_for_chunk =
1001
- m_process_sp->ReadMemory (range.range .start () + * bytes_read,
1002
- data_up-> GetBytes (), bytes_to_read, error);
988
+ m_process_sp->ReadMemory (range.range .start () + bytes_read,
989
+ data_buffer. GetBytes (), bytes_to_read, error);
1003
990
if (error.Fail () || bytes_read_for_chunk == 0 ) {
1004
991
LLDB_LOGF (log,
1005
992
" Failed to read memory region at: %" PRIx64
1006
993
" . Bytes read: %zu, error: %s" ,
1007
994
addr, bytes_read_for_chunk, error.AsCString ());
1008
995
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.
996
+ // If we failed in a memory read, we would normally want to skip
997
+ // this entire region, if we had already written to the minidump
998
+ // file, we can't easily rewind the state.
999
+ //
1000
+ // So if we do encounter an error while reading, we just return
1001
+ // immediately, any prior bytes read will still be included but
1002
+ // any bytes partially read before the error are ignored.
1013
1003
return Status ();
1014
- } else if (bytes_read_for_chunk != bytes_to_read) {
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);
1020
-
1021
- // If we've read some bytes, we stop trying to read more and return
1022
- // this best effort attempt
1023
- partialReadEncountered = true ;
1024
1004
}
1025
1005
1026
1006
// Write to the minidump file with the chunk potentially flushing to disk.
1027
1007
// this is the only place we want to return a true error, so that we can
1028
1008
// fail. If we get an error writing to disk we can't easily gaurauntee
1029
1009
// that we won't corrupt the minidump.
1030
- error = AddData (data_up-> GetBytes (), bytes_read_for_chunk);
1010
+ error = AddData (data_buffer. GetBytes (), bytes_read_for_chunk);
1031
1011
if (error.Fail ())
1032
1012
return error;
1033
1013
@@ -1040,7 +1020,19 @@ Status MinidumpFileBuilder::ReadWriteMemoryInChunks(
1040
1020
1041
1021
// Update the caller with the number of bytes read, but also written to the
1042
1022
// underlying buffer.
1043
- *bytes_read += bytes_read_for_chunk;
1023
+ bytes_read += bytes_read_for_chunk;
1024
+
1025
+ if (bytes_read_for_chunk != bytes_to_read) {
1026
+ LLDB_LOGF (log,
1027
+ " Memory region at: %" PRIx64 " partiall read %" PRIx64
1028
+ " bytes out of %" PRIx64 " bytes." ,
1029
+ addr, bytes_read_for_chunk,
1030
+ bytes_to_read - bytes_read_for_chunk);
1031
+
1032
+ // If we've read some bytes, we stop trying to read more and return
1033
+ // this best effort attempt
1034
+ break ;
1035
+ }
1044
1036
}
1045
1037
1046
1038
return error;
@@ -1064,7 +1056,7 @@ MinidumpFileBuilder::AddMemoryList_32(std::vector<CoreFileMemoryRange> &ranges,
1064
1056
1065
1057
Log *log = GetLog (LLDBLog::Object);
1066
1058
size_t region_index = 0 ;
1067
- auto data_up = std::make_unique< DataBufferHeap> (
1059
+ lldb_private:: DataBufferHeap data_buffer (
1068
1060
std::min (GetLargestRangeSize (ranges), MAX_WRITE_CHUNK_SIZE), 0 );
1069
1061
for (const auto &core_range : ranges) {
1070
1062
// Take the offset before we write.
@@ -1080,8 +1072,8 @@ MinidumpFileBuilder::AddMemoryList_32(std::vector<CoreFileMemoryRange> &ranges,
1080
1072
++region_index;
1081
1073
1082
1074
progress.Increment (1 , " Adding Memory Range " + core_range.Dump ());
1083
- uint64_t bytes_read;
1084
- error = ReadWriteMemoryInChunks (data_up , core_range, & bytes_read);
1075
+ uint64_t bytes_read = 0 ;
1076
+ error = ReadWriteMemoryInChunks (data_buffer , core_range, bytes_read);
1085
1077
if (error.Fail ())
1086
1078
return error;
1087
1079
@@ -1157,7 +1149,7 @@ MinidumpFileBuilder::AddMemoryList_64(std::vector<CoreFileMemoryRange> &ranges,
1157
1149
list_header.BaseRVA = memory_ranges_base_rva;
1158
1150
m_data.AppendData (&list_header, sizeof (llvm::minidump::Memory64ListHeader));
1159
1151
1160
- auto data_up = std::make_unique< DataBufferHeap> (
1152
+ lldb_private:: DataBufferHeap data_buffer (
1161
1153
std::min (GetLargestRangeSize (ranges), MAX_WRITE_CHUNK_SIZE), 0 );
1162
1154
bool cleanup_required = false ;
1163
1155
std::vector<MemoryDescriptor_64> descriptors;
@@ -1189,8 +1181,8 @@ MinidumpFileBuilder::AddMemoryList_64(std::vector<CoreFileMemoryRange> &ranges,
1189
1181
++region_index;
1190
1182
1191
1183
progress.Increment (1 , " Adding Memory Range " + core_range.Dump ());
1192
- uint64_t bytes_read;
1193
- error = ReadWriteMemoryInChunks (data_up , core_range, & bytes_read);
1184
+ uint64_t bytes_read = 0 ;
1185
+ error = ReadWriteMemoryInChunks (data_buffer , core_range, bytes_read);
1194
1186
if (error.Fail ())
1195
1187
return error;
1196
1188
0 commit comments