diff options
author | Christopher Ferris <cferris@google.com> | 2016-11-14 20:14:17 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2016-11-14 20:14:18 +0000 |
commit | f96e7446fda3be741a10a640b35221bb3d477264 (patch) | |
tree | 6eefb9521c533af153206b5db2cd60eccaa1b80f /libbacktrace | |
parent | 557359863c0d1fcda9a85e3b7fb275cb12a3eb70 (diff) | |
parent | fdb02f8b9c6920d6c5edecabda62e175fc03dcbf (diff) | |
download | core-f96e7446fda3be741a10a640b35221bb3d477264.tar.gz core-f96e7446fda3be741a10a640b35221bb3d477264.tar.bz2 core-f96e7446fda3be741a10a640b35221bb3d477264.zip |
Merge "Revert "Use process_vm_readv to read memory.""
Diffstat (limited to 'libbacktrace')
-rw-r--r-- | libbacktrace/BacktracePtrace.cpp | 45 |
1 files changed, 33 insertions, 12 deletions
diff --git a/libbacktrace/BacktracePtrace.cpp b/libbacktrace/BacktracePtrace.cpp index 148c41810..fd8b7134f 100644 --- a/libbacktrace/BacktracePtrace.cpp +++ b/libbacktrace/BacktracePtrace.cpp @@ -17,7 +17,6 @@ #include <errno.h> #include <stdint.h> #include <string.h> -#include <sys/uio.h> #include <sys/param.h> #include <sys/ptrace.h> #include <sys/types.h> @@ -73,20 +72,42 @@ size_t BacktracePtrace::Read(uintptr_t addr, uint8_t* buffer, size_t bytes) { if (!BacktraceMap::IsValid(map) || !(map.flags & PROT_READ)) { return 0; } - bytes = MIN(map.end - addr, bytes); - struct iovec local_io; - local_io.iov_base = buffer; - local_io.iov_len = bytes; + bytes = MIN(map.end - addr, bytes); + size_t bytes_read = 0; + word_t data_word; + size_t align_bytes = addr & (sizeof(word_t) - 1); + if (align_bytes != 0) { + if (!PtraceRead(Tid(), addr & ~(sizeof(word_t) - 1), &data_word)) { + return 0; + } + size_t copy_bytes = MIN(sizeof(word_t) - align_bytes, bytes); + memcpy(buffer, reinterpret_cast<uint8_t*>(&data_word) + align_bytes, copy_bytes); + addr += copy_bytes; + buffer += copy_bytes; + bytes -= copy_bytes; + bytes_read += copy_bytes; + } - struct iovec remote_io; - remote_io.iov_base = reinterpret_cast<void*>(addr); - remote_io.iov_len = bytes; + size_t num_words = bytes / sizeof(word_t); + for (size_t i = 0; i < num_words; i++) { + if (!PtraceRead(Tid(), addr, &data_word)) { + return bytes_read; + } + memcpy(buffer, &data_word, sizeof(word_t)); + buffer += sizeof(word_t); + addr += sizeof(word_t); + bytes_read += sizeof(word_t); + } - ssize_t bytes_read = process_vm_readv(Tid(), &local_io, 1, &remote_io, 1, 0); - if (bytes_read == -1) { - return 0; + size_t left_over = bytes & (sizeof(word_t) - 1); + if (left_over) { + if (!PtraceRead(Tid(), addr, &data_word)) { + return bytes_read; + } + memcpy(buffer, &data_word, left_over); + bytes_read += left_over; } - return static_cast<size_t>(bytes_read); + return bytes_read; #endif } |