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
diff --git a/debuggerd/libdebuggerd/utility.cpp b/debuggerd/libdebuggerd/utility.cpp
index 7826efc..f406ad4 100644
--- a/debuggerd/libdebuggerd/utility.cpp
+++ b/debuggerd/libdebuggerd/utility.cpp
@@ -126,56 +126,56 @@
#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 @@
}
// 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 @@
// 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 @@
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.