diff options
author | Josh Gao <jmgao@google.com> | 2021-01-26 15:53:11 -0800 |
---|---|---|
committer | Josh Gao <jmgao@google.com> | 2021-01-26 17:55:17 -0800 |
commit | 76e1e30f16d8de3e0de2dabcef3c774973b9dd9c (patch) | |
tree | 8e5d85f5ea79413c208c6b2dbac0961d31c6c586 /debuggerd/libdebuggerd/utility.cpp | |
parent | e8cc75f059d9758fd255e46bd6f13b8a040820e0 (diff) |
Reland protobuf tombstones.
This reverts the following commits:
e156ede145a7fc671c705d045d89b49922a758b5.
eda96eddcbdda9632166232b2363c7b84da0994d.
5ec54d1e843729cd1e38a2f791f001226a653e95.
1e45d3f2239333217d3252f78151f4294fda4e80.
a50f61f8fa903117a6df82d164628de310f16ae9.
Test: treehugger
Test: atest -c CtsSeccompHostTestCases:android.seccomp.cts.SeccompHostJUnit4DeviceTest#testAppZygoteSyscalls
Change-Id: Ic2b1f489ac9f1fec7d7a33c845c29891f4306bbd
Diffstat (limited to 'debuggerd/libdebuggerd/utility.cpp')
-rw-r--r-- | debuggerd/libdebuggerd/utility.cpp | 54 |
1 files changed, 33 insertions, 21 deletions
diff --git a/debuggerd/libdebuggerd/utility.cpp b/debuggerd/libdebuggerd/utility.cpp index 7826efc5e..f406ad48e 100644 --- a/debuggerd/libdebuggerd/utility.cpp +++ b/debuggerd/libdebuggerd/utility.cpp @@ -126,56 +126,56 @@ void _VLOG(log_t* log, enum logtype ltype, const char* fmt, va_list ap) { #define MEMORY_BYTES_TO_DUMP 256 #define MEMORY_BYTES_PER_LINE 16 -void dump_memory(log_t* log, unwindstack::Memory* memory, uint64_t addr, const std::string& label) { +ssize_t dump_memory(void* out, size_t len, size_t* start_offset, uint64_t* addr, + unwindstack::Memory* memory) { // Align the address to the number of bytes per line to avoid confusing memory tag output if // memory is tagged and we start from a misaligned address. Start 32 bytes before the address. - addr &= ~(MEMORY_BYTES_PER_LINE - 1); - if (addr >= 4128) { - addr -= 32; + *addr &= ~(MEMORY_BYTES_PER_LINE - 1); + if (*addr >= 4128) { + *addr -= 32; } // We don't want the address tag to appear in the addresses in the memory dump. - addr = untag_address(addr); + *addr = untag_address(*addr); // Don't bother if the address would overflow, taking tag bits into account. Note that // untag_address truncates to 32 bits on 32-bit platforms as a side effect of returning a // uintptr_t, so this also checks for 32-bit overflow. - if (untag_address(addr + MEMORY_BYTES_TO_DUMP - 1) < addr) { - return; + if (untag_address(*addr + MEMORY_BYTES_TO_DUMP - 1) < *addr) { + return -1; } - // Dump 256 bytes - uintptr_t data[MEMORY_BYTES_TO_DUMP/sizeof(uintptr_t)]; - memset(data, 0, MEMORY_BYTES_TO_DUMP); - size_t bytes = memory->Read(addr, reinterpret_cast<uint8_t*>(data), sizeof(data)); + memset(out, 0, len); + + size_t bytes = memory->Read(*addr, reinterpret_cast<uint8_t*>(out), len); if (bytes % sizeof(uintptr_t) != 0) { // This should never happen, but just in case. ALOGE("Bytes read %zu, is not a multiple of %zu", bytes, sizeof(uintptr_t)); bytes &= ~(sizeof(uintptr_t) - 1); } - uint64_t start = 0; + *start_offset = 0; bool skip_2nd_read = false; if (bytes == 0) { // In this case, we might want to try another read at the beginning of // the next page only if it's within the amount of memory we would have // read. 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) { + *start_offset = ((*addr + (page_size - 1)) & ~(page_size - 1)) - *addr; + if (*start_offset == 0 || *start_offset >= len) { skip_2nd_read = true; } } - if (bytes < MEMORY_BYTES_TO_DUMP && !skip_2nd_read) { + if (bytes < len && !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 = memory->Read(addr + start + bytes, reinterpret_cast<uint8_t*>(data) + bytes, - sizeof(data) - bytes - start); + size_t bytes2 = memory->Read(*addr + *start_offset + bytes, static_cast<uint8_t*>(out) + bytes, + len - bytes - *start_offset); bytes += bytes2; if (bytes2 > 0 && bytes % sizeof(uintptr_t) != 0) { // This should never happen, but we'll try and continue any way. @@ -185,9 +185,21 @@ void dump_memory(log_t* log, unwindstack::Memory* memory, uint64_t addr, const s } // If we were unable to read anything, it probably means that the register doesn't contain a - // valid pointer. In that case, skip the output for this register entirely rather than emitting 16 - // lines of dashes. + // valid pointer. if (bytes == 0) { + return -1; + } + + return bytes; +} + +void dump_memory(log_t* log, unwindstack::Memory* memory, uint64_t addr, const std::string& label) { + // Dump 256 bytes + uintptr_t data[MEMORY_BYTES_TO_DUMP / sizeof(uintptr_t)]; + size_t start_offset = 0; + + ssize_t bytes = dump_memory(data, sizeof(data), &start_offset, &addr, memory); + if (bytes == -1) { return; } @@ -201,7 +213,7 @@ void dump_memory(log_t* log, unwindstack::Memory* memory, uint64_t addr, const s // words are of course presented differently. uintptr_t* data_ptr = data; size_t current = 0; - size_t total_bytes = start + bytes; + size_t total_bytes = start_offset + bytes; for (size_t line = 0; line < MEMORY_BYTES_TO_DUMP / MEMORY_BYTES_PER_LINE; line++) { uint64_t tagged_addr = addr; long tag = memory->ReadTag(addr); @@ -214,7 +226,7 @@ void dump_memory(log_t* log, unwindstack::Memory* memory, uint64_t addr, const s addr += MEMORY_BYTES_PER_LINE; std::string ascii; for (size_t i = 0; i < MEMORY_BYTES_PER_LINE / sizeof(uintptr_t); i++) { - if (current >= start && current + sizeof(uintptr_t) <= total_bytes) { + if (current >= start_offset && current + sizeof(uintptr_t) <= total_bytes) { android::base::StringAppendF(&logline, " %" PRIPTR, static_cast<uint64_t>(*data_ptr)); // Fill out the ascii string from the data. |