Skip to content

Commit aa23a39

Browse files
committed
Update Minidump file builder to use new API
Run GCF
1 parent 0d31bb6 commit aa23a39

File tree

3 files changed

+71
-63
lines changed

3 files changed

+71
-63
lines changed

lldb/include/lldb/Target/Process.h

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1589,10 +1589,19 @@ class Process : public std::enable_shared_from_this<Process>,
15891589
size_t ReadMemoryFromInferior(lldb::addr_t vm_addr, void *buf, size_t size,
15901590
Status &error);
15911591

1592-
typedef lldb::IterationAction(ReadMemoryChunkCallback)(lldb::Status &,
1593-
DataBufferHeap &, lldb
1594-
: addr_t,
1595-
lldb::offset_t);
1592+
// Callback definition for read Memory in chunks
1593+
//
1594+
// Status, the status returned from ReadMemoryFromInferior
1595+
// uint8_t*, pointer to the bytes read
1596+
// addr_t, the current_addr, start + bytes read so far.
1597+
// uint64_t bytes_to_read, the expected bytes read, this
1598+
// is important if it's a partial read
1599+
// uint64_t bytes_read_for_chunk, the actual count of bytes read for this
1600+
// chunk
1601+
typedef std::function<IterationAction(lldb_private::Status &, const void *,
1602+
lldb::addr_t, uint64_t, uint64_t)>
1603+
ReadMemoryChunkCallback;
1604+
15961605
/// Read of memory from a process in discrete chunks, terminating
15971606
/// either when all bytes are read, or the supplied callback returns
15981607
/// IterationAction::Stop
@@ -1610,9 +1619,6 @@ class Process : public std::enable_shared_from_this<Process>,
16101619
///
16111620
/// \param[in] callback
16121621
/// The callback to invoke when a chunk is read from memory.
1613-
/// \param[in] cacheReads
1614-
/// Whether to use the ReadMemory instead of ReadMemory inferior, defaults
1615-
/// to false.
16161622
///
16171623
/// \return
16181624
/// The number of bytes that were actually read into \a buf and
@@ -1622,8 +1628,7 @@ class Process : public std::enable_shared_from_this<Process>,
16221628
/// vm_addr, \a buf, and \a size updated appropriately. Zero is
16231629
/// returned in the case of an error.
16241630
size_t ReadMemoryInChunks(lldb::addr_t vm_addr, DataBufferHeap &data,
1625-
size_t size, ReadMemoryChunkCallback callback,
1626-
bool cacheReads = false);
1631+
size_t size, ReadMemoryChunkCallback callback);
16271632

16281633
/// Read a NULL terminated C string from memory
16291634
///

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

Lines changed: 27 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -974,68 +974,57 @@ Status MinidumpFileBuilder::ReadWriteMemoryInChunks(
974974
const lldb_private::CoreFileMemoryRange &range, uint64_t &bytes_read) {
975975

976976
Log *log = GetLog(LLDBLog::Object);
977-
const lldb::addr_t addr = range.range.start();
978-
const lldb::addr_t size = range.range.size();
979-
980-
uint64_t bytes_remaining = size;
981-
Status error;
982-
while (bytes_remaining > 0) {
983-
// Get the next read chunk size as the minimum of the remaining bytes and
984-
// the write chunk max size.
985-
const size_t bytes_to_read =
986-
std::min(bytes_remaining, data_buffer.GetByteSize());
987-
const size_t bytes_read_for_chunk =
988-
m_process_sp->ReadMemory(range.range.start() + bytes_read,
989-
data_buffer.GetBytes(), bytes_to_read, error);
977+
Status addDataError;
978+
Process::ReadMemoryChunkCallback callback =
979+
[&](Status &error, const void *buf, lldb::addr_t current_addr,
980+
uint64_t bytes_to_read,
981+
uint64_t bytes_read_for_chunk) -> lldb_private::IterationAction {
990982
if (error.Fail() || bytes_read_for_chunk == 0) {
991983
LLDB_LOGF(log,
992984
"Failed to read memory region at: %" PRIx64
993985
". Bytes read: %zu, error: %s",
994-
addr, bytes_read_for_chunk, error.AsCString());
986+
current_addr, bytes_read_for_chunk, error.AsCString());
995987

996988
// If we failed in a memory read, we would normally want to skip
997989
// this entire region, if we had already written to the minidump
998-
// file, we can't easily rewind the state.
990+
// file, we can't easily rewind that state.
999991
//
1000992
// So if we do encounter an error while reading, we just return
1001993
// immediately, any prior bytes read will still be included but
1002994
// any bytes partially read before the error are ignored.
1003-
return Status();
995+
return lldb_private::IterationAction::Stop;
1004996
}
1005997

1006-
// Write to the minidump file with the chunk potentially flushing to disk.
1007-
// this is the only place we want to return a true error, so that we can
1008-
// fail. If we get an error writing to disk we can't easily gaurauntee
1009-
// that we won't corrupt the minidump.
1010-
error = AddData(data_buffer.GetBytes(), bytes_read_for_chunk);
1011-
if (error.Fail())
1012-
return error;
1013-
1014-
// If the bytes read in this chunk would cause us to overflow, something
1015-
// went wrong and we should fail out of creating the Minidump.
1016-
if (bytes_read_for_chunk > bytes_remaining)
1017-
return Status::FromErrorString("Unexpected number of bytes read.");
1018-
else
1019-
bytes_remaining -= bytes_read_for_chunk;
1020-
1021-
// Update the caller with the number of bytes read, but also written to the
1022-
// underlying buffer.
1023-
bytes_read += bytes_read_for_chunk;
998+
// Write to the minidump file with the chunk potentially flushing to
999+
// disk.
1000+
// This error will be captured by the outer scope and is considered fatal.
1001+
// If we get an error writing to disk we can't easily guarauntee that we
1002+
// won't corrupt the minidump.
1003+
addDataError = AddData(buf, bytes_read_for_chunk);
1004+
if (addDataError.Fail())
1005+
return lldb_private::IterationAction::Stop;
10241006

10251007
if (bytes_read_for_chunk != bytes_to_read) {
10261008
LLDB_LOGF(log,
10271009
"Memory region at: %" PRIx64 " partiall read %" PRIx64
10281010
" bytes out of %" PRIx64 " bytes.",
1029-
addr, bytes_read_for_chunk,
1011+
current_addr, bytes_read_for_chunk,
10301012
bytes_to_read - bytes_read_for_chunk);
10311013

10321014
// If we've read some bytes, we stop trying to read more and return
10331015
// this best effort attempt
1034-
break;
1016+
return lldb_private::IterationAction::Stop;
10351017
}
1036-
}
10371018

1038-
return error;
1019+
// No problems, keep going!
1020+
return lldb_private::IterationAction::Continue;
1021+
};
1022+
1023+
const lldb::addr_t addr = range.range.start();
1024+
const lldb::addr_t size = range.range.size();
1025+
bytes_read = m_process_sp->ReadMemoryInChunks(
1026+
addr, data_buffer.GetBytes(), data_buffer.GetByteSize(), size, callback);
1027+
return addDataError;
10391028
}
10401029

10411030
static uint64_t

lldb/source/Target/Process.cpp

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2233,22 +2233,36 @@ size_t Process::ReadMemoryFromInferior(addr_t addr, void *buf, size_t size,
22332233
return bytes_read;
22342234
}
22352235

2236-
size_t Process::ReadMemoryInChunks(lldb::addr_t vm_addr, DataBufferHeap &data,
2237-
size_t size, ReadMemoryChunkCallback callback) {
2238-
uint64_t bytes_remaining = size;
2239-
uint64_t bytes_read = 0;
2240-
Status error;
2241-
while (bytes_remaining > 0) {
2242-
// Get the next read chunk size as the minimum of the remaining bytes and
2243-
// the write chunk max size.
2244-
const size_t bytes_to_read =
2245-
std::min(bytes_remaining, data.GetByteSize());
2246-
const lldb::addr_t current_addr = vm_addr + bytes_read
2247-
const size_t bytes_read_for_chunk =
2248-
m_process_sp->ReadMemory(current_addr,
2249-
data.GetBytes(), bytes_to_read, error);
2250-
if (callback(error, data, current_addr, bytes_read_for_chunk) == lldb::IterationAction::Stop)
2251-
break;
2236+
size_t Process::ReadMemoryInChunks(lldb::addr_t vm_addr, void *buf,
2237+
lldb::addr_t chunk_size, size_t size,
2238+
ReadMemoryChunkCallback callback) {
2239+
// Safety check to prevent an infinite loop.
2240+
if (chunk_size == 0)
2241+
return 0;
2242+
2243+
// Create a data buffer heap of the specified size, initialized to 0.
2244+
uint64_t bytes_remaining = size;
2245+
uint64_t bytes_read = 0;
2246+
Status error;
2247+
while (bytes_remaining > 0) {
2248+
// Get the next read chunk size as the minimum of the remaining bytes and
2249+
// the write chunk max size.
2250+
const size_t bytes_to_read = std::min(bytes_remaining, chunk_size);
2251+
const lldb::addr_t current_addr = vm_addr + bytes_read;
2252+
const size_t bytes_read_for_chunk =
2253+
ReadMemoryFromInferior(current_addr, buf, bytes_to_read, error);
2254+
2255+
if (callback(error, buf, current_addr, bytes_to_read,
2256+
bytes_read_for_chunk) == IterationAction::Stop)
2257+
break;
2258+
2259+
bytes_read += bytes_read_for_chunk;
2260+
// If the bytes read in this chunk would cause us to overflow, something
2261+
// went wrong and we should fail fast.
2262+
if (bytes_read_for_chunk > bytes_remaining)
2263+
return 0;
2264+
else
2265+
bytes_remaining -= bytes_read_for_chunk;
22522266
}
22532267

22542268
return bytes_read;

0 commit comments

Comments
 (0)