Merge "Dump memory going from unreadable to readable."
This commit is contained in:
commit
a3ee46f105
3 changed files with 270 additions and 11 deletions
|
|
@ -60,12 +60,14 @@ class BacktraceMock : public Backtrace {
|
||||||
}
|
}
|
||||||
size_t bytes_available = buffer_.size() - offset;
|
size_t bytes_available = buffer_.size() - offset;
|
||||||
|
|
||||||
if (bytes_partial_read_ > 0) {
|
if (do_partial_read_) {
|
||||||
// Do a partial read.
|
// Do a partial read.
|
||||||
if (bytes > bytes_partial_read_) {
|
if (bytes > bytes_partial_read_) {
|
||||||
bytes = bytes_partial_read_;
|
bytes = bytes_partial_read_;
|
||||||
}
|
}
|
||||||
bytes_partial_read_ -= bytes;
|
bytes_partial_read_ -= bytes;
|
||||||
|
// Only support a single partial read.
|
||||||
|
do_partial_read_ = false;
|
||||||
} else if (bytes > bytes_available) {
|
} else if (bytes > bytes_available) {
|
||||||
bytes = bytes_available;
|
bytes = bytes_available;
|
||||||
}
|
}
|
||||||
|
|
@ -82,6 +84,7 @@ class BacktraceMock : public Backtrace {
|
||||||
buffer_.resize(bytes);
|
buffer_.resize(bytes);
|
||||||
memcpy(buffer_.data(), buffer, bytes);
|
memcpy(buffer_.data(), buffer, bytes);
|
||||||
bytes_partial_read_ = 0;
|
bytes_partial_read_ = 0;
|
||||||
|
do_partial_read_ = false;
|
||||||
last_read_addr_ = 0;
|
last_read_addr_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -90,12 +93,14 @@ class BacktraceMock : public Backtrace {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
bytes_partial_read_ = bytes;
|
bytes_partial_read_ = bytes;
|
||||||
|
do_partial_read_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<uint8_t> buffer_;
|
std::vector<uint8_t> buffer_;
|
||||||
size_t bytes_partial_read_ = 0;
|
size_t bytes_partial_read_ = 0;
|
||||||
uintptr_t last_read_addr_ = 0;
|
uintptr_t last_read_addr_ = 0;
|
||||||
|
bool do_partial_read_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _DEBUGGERD_TEST_BACKTRACE_MOCK_H
|
#endif // _DEBUGGERD_TEST_BACKTRACE_MOCK_H
|
||||||
|
|
|
||||||
|
|
@ -502,3 +502,239 @@ TEST_F(DumpMemoryTest, memory_address_nearly_too_high) {
|
||||||
ASSERT_STREQ("", getFakeLogBuf().c_str());
|
ASSERT_STREQ("", getFakeLogBuf().c_str());
|
||||||
ASSERT_STREQ("", getFakeLogPrint().c_str());
|
ASSERT_STREQ("", getFakeLogPrint().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(DumpMemoryTest, first_read_empty) {
|
||||||
|
uint8_t buffer[256];
|
||||||
|
for (size_t i = 0; i < sizeof(buffer); i++) {
|
||||||
|
buffer[i] = i;
|
||||||
|
}
|
||||||
|
backtrace_mock_->SetReadData(buffer, sizeof(buffer));
|
||||||
|
backtrace_mock_->SetPartialReadAmount(0);
|
||||||
|
|
||||||
|
size_t page_size = sysconf(_SC_PAGE_SIZE);
|
||||||
|
uintptr_t addr = 0x10000020 + page_size - 120;
|
||||||
|
dump_memory(&log_, backtrace_mock_.get(), addr, "memory near %.2s:", "r4");
|
||||||
|
|
||||||
|
std::string tombstone_contents;
|
||||||
|
ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
|
||||||
|
ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
|
||||||
|
const char* expected_dump = \
|
||||||
|
"\nmemory near r4:\n"
|
||||||
|
#if defined(__LP64__)
|
||||||
|
" 0000000010000f88 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000f98 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000fa8 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000fb8 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000fc8 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000fd8 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000fe8 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000ff8 ---------------- 7f7e7d7c7b7a7978 ........xyz{|}~.\n"
|
||||||
|
" 0000000010001008 8786858483828180 8f8e8d8c8b8a8988 ................\n"
|
||||||
|
" 0000000010001018 9796959493929190 9f9e9d9c9b9a9998 ................\n"
|
||||||
|
" 0000000010001028 a7a6a5a4a3a2a1a0 afaeadacabaaa9a8 ................\n"
|
||||||
|
" 0000000010001038 b7b6b5b4b3b2b1b0 bfbebdbcbbbab9b8 ................\n"
|
||||||
|
" 0000000010001048 c7c6c5c4c3c2c1c0 cfcecdcccbcac9c8 ................\n"
|
||||||
|
" 0000000010001058 d7d6d5d4d3d2d1d0 dfdedddcdbdad9d8 ................\n"
|
||||||
|
" 0000000010001068 e7e6e5e4e3e2e1e0 efeeedecebeae9e8 ................\n"
|
||||||
|
" 0000000010001078 f7f6f5f4f3f2f1f0 fffefdfcfbfaf9f8 ................\n";
|
||||||
|
#else
|
||||||
|
" 10000f88 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000f98 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000fa8 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000fb8 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000fc8 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000fd8 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000fe8 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000ff8 -------- -------- 7b7a7978 7f7e7d7c ........xyz{|}~.\n"
|
||||||
|
" 10001008 83828180 87868584 8b8a8988 8f8e8d8c ................\n"
|
||||||
|
" 10001018 93929190 97969594 9b9a9998 9f9e9d9c ................\n"
|
||||||
|
" 10001028 a3a2a1a0 a7a6a5a4 abaaa9a8 afaeadac ................\n"
|
||||||
|
" 10001038 b3b2b1b0 b7b6b5b4 bbbab9b8 bfbebdbc ................\n"
|
||||||
|
" 10001048 c3c2c1c0 c7c6c5c4 cbcac9c8 cfcecdcc ................\n"
|
||||||
|
" 10001058 d3d2d1d0 d7d6d5d4 dbdad9d8 dfdedddc ................\n"
|
||||||
|
" 10001068 e3e2e1e0 e7e6e5e4 ebeae9e8 efeeedec ................\n"
|
||||||
|
" 10001078 f3f2f1f0 f7f6f5f4 fbfaf9f8 fffefdfc ................\n";
|
||||||
|
#endif
|
||||||
|
ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
|
||||||
|
|
||||||
|
// Verify that the log buf is empty, and no error messages.
|
||||||
|
ASSERT_STREQ("", getFakeLogBuf().c_str());
|
||||||
|
ASSERT_STREQ("", getFakeLogPrint().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DumpMemoryTest, first_read_empty_second_read_stops) {
|
||||||
|
uint8_t buffer[224];
|
||||||
|
for (size_t i = 0; i < sizeof(buffer); i++) {
|
||||||
|
buffer[i] = i;
|
||||||
|
}
|
||||||
|
backtrace_mock_->SetReadData(buffer, sizeof(buffer));
|
||||||
|
backtrace_mock_->SetPartialReadAmount(0);
|
||||||
|
|
||||||
|
size_t page_size = sysconf(_SC_PAGE_SIZE);
|
||||||
|
uintptr_t addr = 0x10000020 + page_size - 192;
|
||||||
|
dump_memory(&log_, backtrace_mock_.get(), addr, "memory near %.2s:", "r4");
|
||||||
|
|
||||||
|
std::string tombstone_contents;
|
||||||
|
ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
|
||||||
|
ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
|
||||||
|
const char* expected_dump = \
|
||||||
|
"\nmemory near r4:\n"
|
||||||
|
#if defined(__LP64__)
|
||||||
|
" 0000000010000f40 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000f50 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000f60 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000f70 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000f80 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000f90 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000fa0 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000fb0 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000fc0 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000fd0 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000fe0 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000ff0 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010001000 c7c6c5c4c3c2c1c0 cfcecdcccbcac9c8 ................\n"
|
||||||
|
" 0000000010001010 d7d6d5d4d3d2d1d0 dfdedddcdbdad9d8 ................\n"
|
||||||
|
" 0000000010001020 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010001030 ---------------- ---------------- ................\n";
|
||||||
|
#else
|
||||||
|
" 10000f40 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000f50 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000f60 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000f70 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000f80 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000f90 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000fa0 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000fb0 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000fc0 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000fd0 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000fe0 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000ff0 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10001000 c3c2c1c0 c7c6c5c4 cbcac9c8 cfcecdcc ................\n"
|
||||||
|
" 10001010 d3d2d1d0 d7d6d5d4 dbdad9d8 dfdedddc ................\n"
|
||||||
|
" 10001020 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10001030 -------- -------- -------- -------- ................\n";
|
||||||
|
#endif
|
||||||
|
ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
|
||||||
|
|
||||||
|
// Verify that the log buf is empty, and no error messages.
|
||||||
|
ASSERT_STREQ("", getFakeLogBuf().c_str());
|
||||||
|
ASSERT_STREQ("", getFakeLogPrint().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DumpMemoryTest, first_read_empty_next_page_out_of_range) {
|
||||||
|
uint8_t buffer[256];
|
||||||
|
for (size_t i = 0; i < sizeof(buffer); i++) {
|
||||||
|
buffer[i] = i;
|
||||||
|
}
|
||||||
|
backtrace_mock_->SetReadData(buffer, sizeof(buffer));
|
||||||
|
backtrace_mock_->SetPartialReadAmount(0);
|
||||||
|
|
||||||
|
uintptr_t addr = 0x10000020;
|
||||||
|
dump_memory(&log_, backtrace_mock_.get(), addr, "memory near %.2s:", "r4");
|
||||||
|
|
||||||
|
std::string tombstone_contents;
|
||||||
|
ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
|
||||||
|
ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
|
||||||
|
const char* expected_dump = \
|
||||||
|
"\nmemory near r4:\n"
|
||||||
|
#if defined(__LP64__)
|
||||||
|
" 0000000010000000 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000010 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000020 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000030 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000040 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000050 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000060 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000070 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000080 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000090 ---------------- ---------------- ................\n"
|
||||||
|
" 00000000100000a0 ---------------- ---------------- ................\n"
|
||||||
|
" 00000000100000b0 ---------------- ---------------- ................\n"
|
||||||
|
" 00000000100000c0 ---------------- ---------------- ................\n"
|
||||||
|
" 00000000100000d0 ---------------- ---------------- ................\n"
|
||||||
|
" 00000000100000e0 ---------------- ---------------- ................\n"
|
||||||
|
" 00000000100000f0 ---------------- ---------------- ................\n";
|
||||||
|
#else
|
||||||
|
" 10000000 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000010 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000020 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000030 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000040 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000050 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000060 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000070 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000080 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000090 -------- -------- -------- -------- ................\n"
|
||||||
|
" 100000a0 -------- -------- -------- -------- ................\n"
|
||||||
|
" 100000b0 -------- -------- -------- -------- ................\n"
|
||||||
|
" 100000c0 -------- -------- -------- -------- ................\n"
|
||||||
|
" 100000d0 -------- -------- -------- -------- ................\n"
|
||||||
|
" 100000e0 -------- -------- -------- -------- ................\n"
|
||||||
|
" 100000f0 -------- -------- -------- -------- ................\n";
|
||||||
|
#endif
|
||||||
|
ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
|
||||||
|
|
||||||
|
// Verify that the log buf is empty, and no error messages.
|
||||||
|
ASSERT_STREQ("", getFakeLogBuf().c_str());
|
||||||
|
ASSERT_STREQ("", getFakeLogPrint().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DumpMemoryTest, first_read_empty_next_page_out_of_range_fence_post) {
|
||||||
|
uint8_t buffer[256];
|
||||||
|
for (size_t i = 0; i < sizeof(buffer); i++) {
|
||||||
|
buffer[i] = i;
|
||||||
|
}
|
||||||
|
backtrace_mock_->SetReadData(buffer, sizeof(buffer));
|
||||||
|
backtrace_mock_->SetPartialReadAmount(0);
|
||||||
|
|
||||||
|
size_t page_size = sysconf(_SC_PAGE_SIZE);
|
||||||
|
uintptr_t addr = 0x10000020 + page_size - 256;
|
||||||
|
|
||||||
|
dump_memory(&log_, backtrace_mock_.get(), addr, "memory near %.2s:", "r4");
|
||||||
|
|
||||||
|
std::string tombstone_contents;
|
||||||
|
ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
|
||||||
|
ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
|
||||||
|
const char* expected_dump = \
|
||||||
|
"\nmemory near r4:\n"
|
||||||
|
#if defined(__LP64__)
|
||||||
|
" 0000000010000f00 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000f10 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000f20 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000f30 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000f40 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000f50 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000f60 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000f70 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000f80 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000f90 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000fa0 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000fb0 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000fc0 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000fd0 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000fe0 ---------------- ---------------- ................\n"
|
||||||
|
" 0000000010000ff0 ---------------- ---------------- ................\n";
|
||||||
|
#else
|
||||||
|
" 10000f00 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000f10 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000f20 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000f30 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000f40 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000f50 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000f60 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000f70 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000f80 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000f90 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000fa0 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000fb0 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000fc0 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000fd0 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000fe0 -------- -------- -------- -------- ................\n"
|
||||||
|
" 10000ff0 -------- -------- -------- -------- ................\n";
|
||||||
|
#endif
|
||||||
|
ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
|
||||||
|
|
||||||
|
// Verify that the log buf is empty, and no error messages.
|
||||||
|
ASSERT_STREQ("", getFakeLogBuf().c_str());
|
||||||
|
ASSERT_STREQ("", getFakeLogPrint().c_str());
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -156,13 +156,28 @@ void dump_memory(log_t* log, Backtrace* backtrace, uintptr_t addr, const char* f
|
||||||
bytes &= ~(sizeof(uintptr_t) - 1);
|
bytes &= ~(sizeof(uintptr_t) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bytes < MEMORY_BYTES_TO_DUMP && bytes > 0) {
|
uintptr_t start = 0;
|
||||||
// Try to do one more read. This could happen if a read crosses a map, but
|
bool skip_2nd_read = false;
|
||||||
// the maps do not have any break between them. Only requires one extra
|
if (bytes == 0) {
|
||||||
// read because a map has to contain at least one page, and the total
|
// In this case, we might want to try another read at the beginning of
|
||||||
// number of bytes to dump is smaller than a page.
|
// the next page only if it's within the amount of memory we would have
|
||||||
size_t bytes2 = backtrace->Read(addr + bytes, reinterpret_cast<uint8_t*>(data) + bytes,
|
// read.
|
||||||
sizeof(data) - bytes);
|
size_t page_size = sysconf(_SC_PAGE_SIZE);
|
||||||
|
start = ((addr + (page_size - 1)) & ~(page_size - 1)) - addr;
|
||||||
|
if (start == 0 || start >= MEMORY_BYTES_TO_DUMP) {
|
||||||
|
skip_2nd_read = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bytes < MEMORY_BYTES_TO_DUMP && !skip_2nd_read) {
|
||||||
|
// Try to do one more read. This could happen if a read crosses a map,
|
||||||
|
// but the maps do not have any break between them. Or it could happen
|
||||||
|
// if reading from an unreadable map, but the read would cross back
|
||||||
|
// into a readable map. Only requires one extra read because a map has
|
||||||
|
// to contain at least one page, and the total number of bytes to dump
|
||||||
|
// is smaller than a page.
|
||||||
|
size_t bytes2 = backtrace->Read(addr + start + bytes, reinterpret_cast<uint8_t*>(data) + bytes,
|
||||||
|
sizeof(data) - bytes - start);
|
||||||
bytes += bytes2;
|
bytes += bytes2;
|
||||||
if (bytes2 > 0 && bytes % sizeof(uintptr_t) != 0) {
|
if (bytes2 > 0 && bytes % sizeof(uintptr_t) != 0) {
|
||||||
// This should never happen, but we'll try and continue any way.
|
// This should never happen, but we'll try and continue any way.
|
||||||
|
|
@ -178,15 +193,16 @@ void dump_memory(log_t* log, Backtrace* backtrace, uintptr_t addr, const char* f
|
||||||
// On 32-bit machines, there are still 16 bytes per line but addresses and
|
// On 32-bit machines, there are still 16 bytes per line but addresses and
|
||||||
// words are of course presented differently.
|
// words are of course presented differently.
|
||||||
uintptr_t* data_ptr = data;
|
uintptr_t* data_ptr = data;
|
||||||
|
size_t current = 0;
|
||||||
|
size_t total_bytes = start + bytes;
|
||||||
for (size_t line = 0; line < MEMORY_BYTES_TO_DUMP / MEMORY_BYTES_PER_LINE; line++) {
|
for (size_t line = 0; line < MEMORY_BYTES_TO_DUMP / MEMORY_BYTES_PER_LINE; line++) {
|
||||||
std::string logline;
|
std::string logline;
|
||||||
android::base::StringAppendF(&logline, " %" PRIPTR, addr);
|
android::base::StringAppendF(&logline, " %" PRIPTR, addr);
|
||||||
|
|
||||||
addr += MEMORY_BYTES_PER_LINE;
|
addr += MEMORY_BYTES_PER_LINE;
|
||||||
std::string ascii;
|
std::string ascii;
|
||||||
for (size_t i = 0; i < MEMORY_BYTES_PER_LINE / sizeof(uintptr_t); i++, data_ptr++) {
|
for (size_t i = 0; i < MEMORY_BYTES_PER_LINE / sizeof(uintptr_t); i++) {
|
||||||
if (bytes >= sizeof(uintptr_t)) {
|
if (current >= start && current + sizeof(uintptr_t) <= total_bytes) {
|
||||||
bytes -= sizeof(uintptr_t);
|
|
||||||
android::base::StringAppendF(&logline, " %" PRIPTR, *data_ptr);
|
android::base::StringAppendF(&logline, " %" PRIPTR, *data_ptr);
|
||||||
|
|
||||||
// Fill out the ascii string from the data.
|
// Fill out the ascii string from the data.
|
||||||
|
|
@ -198,10 +214,12 @@ void dump_memory(log_t* log, Backtrace* backtrace, uintptr_t addr, const char* f
|
||||||
ascii += '.';
|
ascii += '.';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
data_ptr++;
|
||||||
} else {
|
} else {
|
||||||
logline += ' ' + std::string(sizeof(uintptr_t) * 2, '-');
|
logline += ' ' + std::string(sizeof(uintptr_t) * 2, '-');
|
||||||
ascii += std::string(sizeof(uintptr_t), '.');
|
ascii += std::string(sizeof(uintptr_t), '.');
|
||||||
}
|
}
|
||||||
|
current += sizeof(uintptr_t);
|
||||||
}
|
}
|
||||||
_LOG(log, logtype::MEMORY, "%s %s\n", logline.c_str(), ascii.c_str());
|
_LOG(log, logtype::MEMORY, "%s %s\n", logline.c_str(), ascii.c_str());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue