Skip to content

Commit 4aed212

Browse files
committed
Redo callback prototype and refactor to not pass expected size and the read chunk size. Also don't log if a truncated read is the final read
1 parent 13581a6 commit 4aed212

File tree

3 files changed

+46
-37
lines changed

3 files changed

+46
-37
lines changed

lldb/include/lldb/Target/Process.h

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1592,14 +1592,12 @@ class Process : public std::enable_shared_from_this<Process>,
15921592
// Callback definition for read Memory in chunks
15931593
//
15941594
// 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)>
1595+
// void*, pointer to the bytes read
1596+
// addr_t, the bytes_addr, start + bytes read so far.
1597+
// bytes_size, the count of bytes read for this chunk
1598+
typedef std::function<IterationAction(
1599+
lldb_private::Status &error, lldb::addr_t bytes_addr, const void *bytes,
1600+
lldb::offset_t bytes_size)>
16031601
ReadMemoryChunkCallback;
16041602

16051603
/// Read of memory from a process in discrete chunks, terminating
@@ -1611,15 +1609,16 @@ class Process : public std::enable_shared_from_this<Process>,
16111609
/// memory from.
16121610
///
16131611
/// \param[in] buf
1614-
/// A byte buffer that is at least \a chunk_size bytes long that
1615-
/// will receive the memory bytes.
1612+
/// If NULL, a buffer of \a chunk_size will be created and used for the
1613+
/// callback. If non NULL, this buffer must be at least \a chunk_size bytes
1614+
/// and will be used for storing chunked memory reads.
16161615
///
16171616
/// \param[in] chunk_size
16181617
/// The minimum size of the byte buffer, and the chunk size of memory
16191618
/// to read.
16201619
///
1621-
/// \param[in] size
1622-
/// The number of bytes to read.
1620+
/// \param[in] total_size
1621+
/// The total number of bytes to read.
16231622
///
16241623
/// \param[in] callback
16251624
/// The callback to invoke when a chunk is read from memory.
@@ -1631,8 +1630,8 @@ class Process : public std::enable_shared_from_this<Process>,
16311630
/// size, then this function will get called again with \a
16321631
/// vm_addr, \a buf, and \a size updated appropriately. Zero is
16331632
/// returned in the case of an error.
1634-
size_t ReadMemoryInChunks(lldb::addr_t vm_addr, void *buf,
1635-
lldb::addr_t chunk_size, size_t size,
1633+
lldb::offset_t ReadMemoryInChunks(lldb::addr_t vm_addr, void *buf,
1634+
lldb::addr_t chunk_size, lldb::offset_t total_size,
16361635
ReadMemoryChunkCallback callback);
16371636

16381637
/// Read a NULL terminated C string from memory

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

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -973,17 +973,18 @@ Status MinidumpFileBuilder::ReadWriteMemoryInChunks(
973973
lldb_private::DataBufferHeap &data_buffer,
974974
const lldb_private::CoreFileMemoryRange &range, uint64_t &bytes_read) {
975975

976+
const lldb::addr_t addr = range.range.start();
977+
const lldb::addr_t size = range.range.size();
976978
Log *log = GetLog(LLDBLog::Object);
977979
Status addDataError;
978980
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 {
982-
if (error.Fail() || bytes_read_for_chunk == 0) {
981+
[&](Status &error, lldb::addr_t current_addr, const void *buf,
982+
uint64_t bytes_read) -> lldb_private::IterationAction {
983+
if (error.Fail() || bytes_read == 0) {
983984
LLDB_LOGF(log,
984-
"Failed to read memory region at: %" PRIx64
985-
". Bytes read: %zu, error: %s",
986-
current_addr, bytes_read_for_chunk, error.AsCString());
985+
"Failed to read memory region at: 0x%" PRIx64
986+
". Bytes read: %" PRIx64 ", error: %s",
987+
current_addr, bytes_read, error.AsCString());
987988

988989
// If we failed in a memory read, we would normally want to skip
989990
// this entire region, if we had already written to the minidump
@@ -1000,16 +1001,19 @@ Status MinidumpFileBuilder::ReadWriteMemoryInChunks(
10001001
// This error will be captured by the outer scope and is considered fatal.
10011002
// If we get an error writing to disk we can't easily guarauntee that we
10021003
// won't corrupt the minidump.
1003-
addDataError = AddData(buf, bytes_read_for_chunk);
1004+
addDataError = AddData(buf, bytes_read);
10041005
if (addDataError.Fail())
10051006
return lldb_private::IterationAction::Stop;
10061007

1007-
if (bytes_read_for_chunk != bytes_to_read) {
1008+
// If we have a partial read, report it, but only if the partial read
1009+
// didn't finish reading the entire region.
1010+
if (bytes_read != data_buffer.GetByteSize() &&
1011+
current_addr + bytes_read != size) {
10081012
LLDB_LOGF(log,
1009-
"Memory region at: %" PRIx64 " partiall read %" PRIx64
1013+
"Memory region at: %" PRIx64 " partiall read 0x%" PRIx64
10101014
" bytes out of %" PRIx64 " bytes.",
1011-
current_addr, bytes_read_for_chunk,
1012-
bytes_to_read - bytes_read_for_chunk);
1015+
current_addr, bytes_read,
1016+
data_buffer.GetByteSize() - bytes_read);
10131017

10141018
// If we've read some bytes, we stop trying to read more and return
10151019
// this best effort attempt
@@ -1020,8 +1024,6 @@ Status MinidumpFileBuilder::ReadWriteMemoryInChunks(
10201024
return lldb_private::IterationAction::Continue;
10211025
};
10221026

1023-
const lldb::addr_t addr = range.range.start();
1024-
const lldb::addr_t size = range.range.size();
10251027
bytes_read = m_process_sp->ReadMemoryInChunks(
10261028
addr, data_buffer.GetBytes(), data_buffer.GetByteSize(), size, callback);
10271029
return addDataError;

lldb/source/Target/Process.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2233,36 +2233,44 @@ 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, void *buf,
2237-
lldb::addr_t chunk_size, size_t size,
2236+
lldb::offset_t Process::ReadMemoryInChunks(lldb::addr_t vm_addr, void *buf,
2237+
lldb::addr_t chunk_size, lldb::offset_t size,
22382238
ReadMemoryChunkCallback callback) {
22392239
// Safety check to prevent an infinite loop.
22402240
if (chunk_size == 0)
22412241
return 0;
22422242

2243-
// Create a data buffer heap of the specified size, initialized to 0.
2243+
// Buffer for when a NULL buf is provided, initialized
2244+
// to 0 bytes, we set it to chunk_size and then replace buf
2245+
// with the new buffer.
2246+
DataBufferHeap data_buffer;
2247+
if (!buf) {
2248+
data_buffer.SetByteSize(chunk_size);
2249+
buf = data_buffer.GetBytes();
2250+
}
2251+
22442252
uint64_t bytes_remaining = size;
22452253
uint64_t bytes_read = 0;
22462254
Status error;
22472255
while (bytes_remaining > 0) {
22482256
// Get the next read chunk size as the minimum of the remaining bytes and
22492257
// the write chunk max size.
2250-
const size_t bytes_to_read = std::min(bytes_remaining, chunk_size);
2258+
const lldb::addr_t bytes_to_read = std::min(bytes_remaining, chunk_size);
22512259
const lldb::addr_t current_addr = vm_addr + bytes_read;
2252-
const size_t bytes_read_for_chunk =
2260+
const lldb::addr_t bytes_read_for_chunk =
22532261
ReadMemoryFromInferior(current_addr, buf, bytes_to_read, error);
22542262

2255-
if (callback(error, buf, current_addr, bytes_to_read,
2256-
bytes_read_for_chunk) == IterationAction::Stop)
2257-
break;
2258-
22592263
bytes_read += bytes_read_for_chunk;
22602264
// If the bytes read in this chunk would cause us to overflow, something
22612265
// went wrong and we should fail fast.
22622266
if (bytes_read_for_chunk > bytes_remaining)
22632267
return 0;
22642268
else
22652269
bytes_remaining -= bytes_read_for_chunk;
2270+
2271+
if (callback(error, current_addr, buf, bytes_read_for_chunk) ==
2272+
IterationAction::Stop)
2273+
break;
22662274
}
22672275

22682276
return bytes_read;

0 commit comments

Comments
 (0)