Skip to content

Commit c5b1f49

Browse files
committed
Refactor to Greg's suggestions, drop uniq_ptr/uint64_t*. Move the partial read exit to the end of the loop
1 parent 4818677 commit c5b1f49

File tree

2 files changed

+37
-44
lines changed

2 files changed

+37
-44
lines changed

lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.cpp

Lines changed: 33 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -970,64 +970,44 @@ Status MinidumpFileBuilder::DumpDirectories() const {
970970
}
971971

972972
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) {
977975

978-
if (!bytes_read)
979-
return Status::FromErrorString("Bytes read pointer cannot be null.");
980976
Log *log = GetLog(LLDBLog::Object);
981977
const lldb::addr_t addr = range.range.start();
982978
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;
987979

988980
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;
994981
Status error;
995-
while (bytes_remaining > 0 && !partialReadEncountered) {
982+
while (bytes_remaining > 0) {
996983
// Get the next read chunk size as the minimum of the remaining bytes and
997984
// the write chunk max size.
998985
const size_t bytes_to_read =
999-
std::min(bytes_remaining, data_up->GetByteSize());
986+
std::min(bytes_remaining, data_buffer.GetByteSize());
1000987
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);
1003990
if (error.Fail() || bytes_read_for_chunk == 0) {
1004991
LLDB_LOGF(log,
1005992
"Failed to read memory region at: %" PRIx64
1006993
". Bytes read: %zu, error: %s",
1007994
addr, bytes_read_for_chunk, error.AsCString());
1008995

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.
10131003
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;
10241004
}
10251005

10261006
// Write to the minidump file with the chunk potentially flushing to disk.
10271007
// this is the only place we want to return a true error, so that we can
10281008
// fail. If we get an error writing to disk we can't easily gaurauntee
10291009
// 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);
10311011
if (error.Fail())
10321012
return error;
10331013

@@ -1040,7 +1020,19 @@ Status MinidumpFileBuilder::ReadWriteMemoryInChunks(
10401020

10411021
// Update the caller with the number of bytes read, but also written to the
10421022
// 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+
}
10441036
}
10451037

10461038
return error;
@@ -1064,7 +1056,7 @@ MinidumpFileBuilder::AddMemoryList_32(std::vector<CoreFileMemoryRange> &ranges,
10641056

10651057
Log *log = GetLog(LLDBLog::Object);
10661058
size_t region_index = 0;
1067-
auto data_up = std::make_unique<DataBufferHeap>(
1059+
lldb_private::DataBufferHeap data_buffer(
10681060
std::min(GetLargestRangeSize(ranges), MAX_WRITE_CHUNK_SIZE), 0);
10691061
for (const auto &core_range : ranges) {
10701062
// Take the offset before we write.
@@ -1080,8 +1072,8 @@ MinidumpFileBuilder::AddMemoryList_32(std::vector<CoreFileMemoryRange> &ranges,
10801072
++region_index;
10811073

10821074
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);
10851077
if (error.Fail())
10861078
return error;
10871079

@@ -1157,7 +1149,7 @@ MinidumpFileBuilder::AddMemoryList_64(std::vector<CoreFileMemoryRange> &ranges,
11571149
list_header.BaseRVA = memory_ranges_base_rva;
11581150
m_data.AppendData(&list_header, sizeof(llvm::minidump::Memory64ListHeader));
11591151

1160-
auto data_up = std::make_unique<DataBufferHeap>(
1152+
lldb_private::DataBufferHeap data_buffer(
11611153
std::min(GetLargestRangeSize(ranges), MAX_WRITE_CHUNK_SIZE), 0);
11621154
bool cleanup_required = false;
11631155
std::vector<MemoryDescriptor_64> descriptors;
@@ -1189,8 +1181,8 @@ MinidumpFileBuilder::AddMemoryList_64(std::vector<CoreFileMemoryRange> &ranges,
11891181
++region_index;
11901182

11911183
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);
11941186
if (error.Fail())
11951187
return error;
11961188

lldb/source/Plugins/ObjectFile/Minidump/MinidumpFileBuilder.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,10 @@ class MinidumpFileBuilder {
145145

146146
// Read a memory region from the process and write it to the file
147147
// in fixed size chunks.
148-
lldb_private::Status ReadWriteMemoryInChunks(
149-
const std::unique_ptr<lldb_private::DataBufferHeap> &data_up,
150-
const lldb_private::CoreFileMemoryRange &range, uint64_t *bytes_read);
148+
lldb_private::Status
149+
ReadWriteMemoryInChunks(lldb_private::DataBufferHeap &data_buffer,
150+
const lldb_private::CoreFileMemoryRange &range,
151+
uint64_t &bytes_read);
151152

152153
// Stores directories to fill in later
153154
std::vector<llvm::minidump::Directory> m_directories;

0 commit comments

Comments
 (0)