From 7937a36c8e24ef2dc5105a2a6b67f395934b2e2f Mon Sep 17 00:00:00 2001 From: Christopher Ferris Date: Thu, 18 Jan 2018 11:15:49 -0800 Subject: Change all uintptr_t to uint64_t in API. In order to support the offline unwinding properly, get rid of the usage of non-fixed type uintptr_t from all API calls. In addition, completely remove the old local and remote unwinding code that used libunwind. The next step will be to move the offline unwinding to the new unwinder. Bug: 65682279 Test: Ran unit tests for libbacktrace/debuggerd. Test: Ran debuggerd -b on a few arm and arm64 processes. Test: Ran crasher and crasher64 and verified tombstones look correct. Change-Id: Ib0c6cee3ad6785a102b74908a3d8e5e93e5c6b33 --- .../libdebuggerd/include/libdebuggerd/tombstone.h | 6 +- .../libdebuggerd/include/libdebuggerd/utility.h | 2 +- debuggerd/libdebuggerd/test/tombstone_test.cpp | 4 +- debuggerd/libdebuggerd/tombstone.cpp | 36 ++-- debuggerd/libdebuggerd/utility.cpp | 6 +- libbacktrace/Android.bp | 3 - libbacktrace/Backtrace.cpp | 12 +- libbacktrace/BacktraceCurrent.cpp | 4 +- libbacktrace/BacktraceCurrent.h | 4 +- libbacktrace/BacktraceMap.cpp | 2 +- libbacktrace/BacktraceOffline.cpp | 17 +- libbacktrace/BacktraceOffline.h | 6 +- libbacktrace/BacktracePtrace.cpp | 6 +- libbacktrace/BacktracePtrace.h | 4 +- libbacktrace/UnwindCurrent.cpp | 165 ------------------ libbacktrace/UnwindCurrent.h | 51 ------ libbacktrace/UnwindMap.cpp | 2 +- libbacktrace/UnwindMap.h | 2 +- libbacktrace/UnwindPtrace.cpp | 186 --------------------- libbacktrace/UnwindPtrace.h | 48 ------ libbacktrace/UnwindStack.cpp | 6 +- libbacktrace/UnwindStack.h | 6 +- libbacktrace/UnwindStackMap.cpp | 8 +- libbacktrace/UnwindStackMap.h | 4 +- libbacktrace/backtrace_offline_test.cpp | 43 +++-- libbacktrace/backtrace_test.cpp | 115 ++++++------- libbacktrace/include/backtrace/Backtrace.h | 27 +-- libbacktrace/include/backtrace/BacktraceMap.h | 22 +-- 28 files changed, 171 insertions(+), 626 deletions(-) delete mode 100644 libbacktrace/UnwindCurrent.cpp delete mode 100644 libbacktrace/UnwindCurrent.h delete mode 100644 libbacktrace/UnwindPtrace.cpp delete mode 100644 libbacktrace/UnwindPtrace.h diff --git a/debuggerd/libdebuggerd/include/libdebuggerd/tombstone.h b/debuggerd/libdebuggerd/include/libdebuggerd/tombstone.h index 198c48b26..be90d0f0b 100644 --- a/debuggerd/libdebuggerd/include/libdebuggerd/tombstone.h +++ b/debuggerd/libdebuggerd/include/libdebuggerd/tombstone.h @@ -40,16 +40,16 @@ int open_tombstone(std::string* path); /* Creates a tombstone file and writes the crash dump to it. */ void engrave_tombstone(int tombstone_fd, BacktraceMap* map, const OpenFilesList* open_files, pid_t pid, pid_t tid, const std::string& process_name, - const std::map& threads, uintptr_t abort_msg_address, + const std::map& threads, uint64_t abort_msg_address, std::string* amfd_data); -void engrave_tombstone_ucontext(int tombstone_fd, uintptr_t abort_msg_address, siginfo_t* siginfo, +void engrave_tombstone_ucontext(int tombstone_fd, uint64_t abort_msg_address, siginfo_t* siginfo, ucontext_t* ucontext); void engrave_tombstone(android::base::unique_fd output_fd, BacktraceMap* map, unwindstack::Memory* process_memory, const std::map& thread_info, pid_t target_thread, - uintptr_t abort_msg_address, OpenFilesList* open_files, + uint64_t abort_msg_address, OpenFilesList* open_files, std::string* amfd_data); #endif // _DEBUGGERD_TOMBSTONE_H diff --git a/debuggerd/libdebuggerd/include/libdebuggerd/utility.h b/debuggerd/libdebuggerd/include/libdebuggerd/utility.h index c5abfe24f..0f049fd25 100644 --- a/debuggerd/libdebuggerd/include/libdebuggerd/utility.h +++ b/debuggerd/libdebuggerd/include/libdebuggerd/utility.h @@ -68,7 +68,7 @@ namespace unwindstack { class Memory; } -void dump_memory(log_t* log, unwindstack::Memory* backtrace, uintptr_t addr, const char* fmt, ...); +void dump_memory(log_t* log, unwindstack::Memory* backtrace, uint64_t addr, const char* fmt, ...); void read_with_default(const char* path, char* buf, size_t len, const char* default_value); diff --git a/debuggerd/libdebuggerd/test/tombstone_test.cpp b/debuggerd/libdebuggerd/test/tombstone_test.cpp index 1e3a10f08..421ce43c0 100644 --- a/debuggerd/libdebuggerd/test/tombstone_test.cpp +++ b/debuggerd/libdebuggerd/test/tombstone_test.cpp @@ -437,9 +437,9 @@ TEST_F(TombstoneTest, multiple_maps_fault_address_after) { map_mock_->AddMap(map); #if defined(__LP64__) - uintptr_t addr = 0x12345a534040UL; + uint64_t addr = 0x12345a534040UL; #else - uintptr_t addr = 0xf534040UL; + uint64_t addr = 0xf534040UL; #endif dump_all_maps(&log_, map_mock_.get(), nullptr, addr); diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp index 89a125b80..320e5dbb9 100644 --- a/debuggerd/libdebuggerd/tombstone.cpp +++ b/debuggerd/libdebuggerd/tombstone.cpp @@ -127,7 +127,7 @@ static void dump_thread_info(log_t* log, const ThreadInfo& thread_info) { } static void dump_stack_segment(log_t* log, BacktraceMap* backtrace_map, Memory* process_memory, - uintptr_t* sp, size_t words, int label) { + uint64_t* sp, size_t words, int label) { // Read the data all at once. word_t stack_data[words]; @@ -144,18 +144,18 @@ static void dump_stack_segment(log_t* log, BacktraceMap* backtrace_map, Memory* } else { line += " "; } - line += StringPrintf("%" PRIPTR " %" PRIPTR, *sp, stack_data[i]); + line += StringPrintf("%" PRIPTR " %" PRIxPTR, *sp, stack_data[i]); backtrace_map_t map; backtrace_map->FillIn(stack_data[i], &map); if (BacktraceMap::IsValid(map) && !map.name.empty()) { line += " " + map.name; - uintptr_t offset = 0; + uint64_t offset = 0; std::string func_name = backtrace_map->GetFunctionName(stack_data[i], &offset); if (!func_name.empty()) { line += " (" + func_name; if (offset) { - line += StringPrintf("+%" PRIuPTR, offset); + line += StringPrintf("+%" PRIu64, offset); } line += ')'; } @@ -185,7 +185,7 @@ static void dump_stack(log_t* log, BacktraceMap* backtrace_map, Memory* process_ first--; // Dump a few words before the first frame. - word_t sp = frames[first].sp - STACK_WORDS * sizeof(word_t); + uint64_t sp = frames[first].sp - STACK_WORDS * sizeof(word_t); dump_stack_segment(log, backtrace_map, process_memory, &sp, STACK_WORDS, -1); // Dump a few words from all successive frames. @@ -213,19 +213,19 @@ static void dump_stack(log_t* log, BacktraceMap* backtrace_map, Memory* process_ } } -static std::string get_addr_string(uintptr_t addr) { +static std::string get_addr_string(uint64_t addr) { std::string addr_str; #if defined(__LP64__) addr_str = StringPrintf("%08x'%08x", static_cast(addr >> 32), static_cast(addr & 0xffffffff)); #else - addr_str = StringPrintf("%08x", addr); + addr_str = StringPrintf("%08x", static_cast(addr)); #endif return addr_str; } -static void dump_abort_message(log_t* log, Memory* process_memory, uintptr_t address) { +static void dump_abort_message(log_t* log, Memory* process_memory, uint64_t address) { if (address == 0) { return; } @@ -251,7 +251,7 @@ static void dump_abort_message(log_t* log, Memory* process_memory, uintptr_t add _LOG(log, logtype::HEADER, "Abort message: '%s'\n", msg); } -static void dump_all_maps(log_t* log, BacktraceMap* map, Memory* process_memory, uintptr_t addr) { +static void dump_all_maps(log_t* log, BacktraceMap* map, Memory* process_memory, uint64_t addr) { bool print_fault_address_marker = addr; ScopedBacktraceMapIteratorLock lock(map); @@ -301,7 +301,7 @@ static void dump_all_maps(log_t* log, BacktraceMap* map, Memory* process_memory, } else { line += '-'; } - line += StringPrintf(" %8" PRIxPTR " %8" PRIxPTR, entry->offset, entry->end - entry->start); + line += StringPrintf(" %8" PRIx64 " %8" PRIx64, entry->offset, entry->end - entry->start); bool space_needed = true; if (entry->name.length() > 0) { space_needed = false; @@ -315,7 +315,7 @@ static void dump_all_maps(log_t* log, BacktraceMap* map, Memory* process_memory, if (space_needed) { line += ' '; } - line += StringPrintf(" (load bias 0x%" PRIxPTR ")", entry->load_bias); + line += StringPrintf(" (load bias 0x%" PRIx64 ")", entry->load_bias); } _LOG(log, logtype::MAPS, "%s\n", line.c_str()); } @@ -335,9 +335,9 @@ static void print_register_row(log_t* log, const std::vector>& registers) { std::string output; for (auto& [name, value] : registers) { - output += android::base::StringPrintf(" %-3s %0*" PRIxPTR, name.c_str(), + output += android::base::StringPrintf(" %-3s %0*" PRIx64, name.c_str(), static_cast(2 * sizeof(void*)), - static_cast(value)); + static_cast(value)); } _LOG(log, logtype::REGISTERS, " %s\n", output.c_str()); @@ -389,7 +389,7 @@ void dump_memory_and_code(log_t* log, Memory* memory, Regs* regs) { } static bool dump_thread(log_t* log, BacktraceMap* map, Memory* process_memory, - const ThreadInfo& thread_info, uintptr_t abort_msg_address, + const ThreadInfo& thread_info, uint64_t abort_msg_address, bool primary_thread) { UNUSED(process_memory); log->current_tid = thread_info.tid; @@ -425,10 +425,10 @@ static bool dump_thread(log_t* log, BacktraceMap* map, Memory* process_memory, if (primary_thread) { dump_memory_and_code(log, process_memory, thread_info.registers.get()); if (map) { - uintptr_t addr = 0; + uint64_t addr = 0; siginfo_t* si = thread_info.siginfo; if (signal_has_si_addr(si->si_signo, si->si_code)) { - addr = reinterpret_cast(si->si_addr); + addr = reinterpret_cast(si->si_addr); } dump_all_maps(log, map, process_memory, addr); } @@ -572,7 +572,7 @@ static void dump_logs(log_t* log, pid_t pid, unsigned int tail) { dump_log_file(log, pid, "main", tail); } -void engrave_tombstone_ucontext(int tombstone_fd, uintptr_t abort_msg_address, siginfo_t* siginfo, +void engrave_tombstone_ucontext(int tombstone_fd, uint64_t abort_msg_address, siginfo_t* siginfo, ucontext_t* ucontext) { pid_t pid = getpid(); pid_t tid = gettid(); @@ -614,7 +614,7 @@ void engrave_tombstone_ucontext(int tombstone_fd, uintptr_t abort_msg_address, s void engrave_tombstone(unique_fd output_fd, BacktraceMap* map, Memory* process_memory, const std::map& threads, pid_t target_thread, - uintptr_t abort_msg_address, OpenFilesList* open_files, + uint64_t abort_msg_address, OpenFilesList* open_files, std::string* amfd_data) { // don't copy log messages to tombstone unless this is a dev device bool want_logs = android::base::GetBoolProperty("ro.debuggable", false); diff --git a/debuggerd/libdebuggerd/utility.cpp b/debuggerd/libdebuggerd/utility.cpp index 247d806ba..3ac98f58f 100644 --- a/debuggerd/libdebuggerd/utility.cpp +++ b/debuggerd/libdebuggerd/utility.cpp @@ -124,7 +124,7 @@ void _LOG(log_t* log, enum logtype ltype, const char* fmt, ...) { #define MEMORY_BYTES_TO_DUMP 256 #define MEMORY_BYTES_PER_LINE 16 -void dump_memory(log_t* log, unwindstack::Memory* memory, uintptr_t addr, const char* fmt, ...) { +void dump_memory(log_t* log, unwindstack::Memory* memory, uint64_t addr, const char* fmt, ...) { std::string log_msg; va_list ap; va_start(ap, fmt); @@ -159,7 +159,7 @@ void dump_memory(log_t* log, unwindstack::Memory* memory, uintptr_t addr, const bytes &= ~(sizeof(uintptr_t) - 1); } - uintptr_t start = 0; + uint64_t start = 0; bool skip_2nd_read = false; if (bytes == 0) { // In this case, we might want to try another read at the beginning of @@ -206,7 +206,7 @@ void dump_memory(log_t* log, unwindstack::Memory* memory, uintptr_t addr, const 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) { - android::base::StringAppendF(&logline, " %" PRIPTR, *data_ptr); + android::base::StringAppendF(&logline, " %" PRIPTR, static_cast(*data_ptr)); // Fill out the ascii string from the data. uint8_t* ptr = reinterpret_cast(data_ptr); diff --git a/libbacktrace/Android.bp b/libbacktrace/Android.bp index 9eaeae870..d9eed7638 100644 --- a/libbacktrace/Android.bp +++ b/libbacktrace/Android.bp @@ -50,9 +50,6 @@ libbacktrace_sources = [ "BacktracePtrace.cpp", "thread_utils.c", "ThreadEntry.cpp", - "UnwindCurrent.cpp", - "UnwindMap.cpp", - "UnwindPtrace.cpp", "UnwindStack.cpp", "UnwindStackMap.cpp", ] diff --git a/libbacktrace/Backtrace.cpp b/libbacktrace/Backtrace.cpp index 5bb6edc8f..1195e5f26 100644 --- a/libbacktrace/Backtrace.cpp +++ b/libbacktrace/Backtrace.cpp @@ -30,8 +30,6 @@ #include #include "BacktraceLog.h" -#include "UnwindCurrent.h" -#include "UnwindPtrace.h" #include "UnwindStack.h" #include "thread_utils.h" @@ -55,7 +53,7 @@ Backtrace::~Backtrace() { } } -std::string Backtrace::GetFunctionName(uintptr_t pc, uintptr_t* offset, const backtrace_map_t* map) { +std::string Backtrace::GetFunctionName(uint64_t pc, uint64_t* offset, const backtrace_map_t* map) { backtrace_map_t map_value; if (map == nullptr) { FillInMap(pc, &map_value); @@ -68,7 +66,7 @@ std::string Backtrace::GetFunctionName(uintptr_t pc, uintptr_t* offset, const ba return demangle(GetFunctionNameRaw(pc, offset).c_str()); } -bool Backtrace::VerifyReadWordArgs(uintptr_t ptr, word_t* out_value) { +bool Backtrace::VerifyReadWordArgs(uint64_t ptr, word_t* out_value) { if (ptr & (sizeof(word_t)-1)) { BACK_LOGW("invalid pointer %p", reinterpret_cast(ptr)); *out_value = static_cast(-1); @@ -105,12 +103,12 @@ std::string Backtrace::FormatFrameData(const backtrace_frame_data_t* frame) { // Special handling for non-zero offset maps, we need to print that // information. if (frame->map.offset != 0) { - line += " (offset " + StringPrintf("0x%" PRIxPTR, frame->map.offset) + ")"; + line += " (offset " + StringPrintf("0x%" PRIx64, frame->map.offset) + ")"; } if (!frame->func_name.empty()) { line += " (" + frame->func_name; if (frame->func_offset) { - line += StringPrintf("+%" PRIuPTR, frame->func_offset); + line += StringPrintf("+%" PRIu64, frame->func_offset); } line += ')'; } @@ -118,7 +116,7 @@ std::string Backtrace::FormatFrameData(const backtrace_frame_data_t* frame) { return line; } -void Backtrace::FillInMap(uintptr_t pc, backtrace_map_t* map) { +void Backtrace::FillInMap(uint64_t pc, backtrace_map_t* map) { if (map_ != nullptr) { map_->FillIn(pc, map); } diff --git a/libbacktrace/BacktraceCurrent.cpp b/libbacktrace/BacktraceCurrent.cpp index 474d09924..d61b28147 100644 --- a/libbacktrace/BacktraceCurrent.cpp +++ b/libbacktrace/BacktraceCurrent.cpp @@ -36,7 +36,7 @@ #include "ThreadEntry.h" #include "thread_utils.h" -bool BacktraceCurrent::ReadWord(uintptr_t ptr, word_t* out_value) { +bool BacktraceCurrent::ReadWord(uint64_t ptr, word_t* out_value) { if (!VerifyReadWordArgs(ptr, out_value)) { return false; } @@ -53,7 +53,7 @@ bool BacktraceCurrent::ReadWord(uintptr_t ptr, word_t* out_value) { } } -size_t BacktraceCurrent::Read(uintptr_t addr, uint8_t* buffer, size_t bytes) { +size_t BacktraceCurrent::Read(uint64_t addr, uint8_t* buffer, size_t bytes) { backtrace_map_t map; FillInMap(addr, &map); if (!BacktraceMap::IsValid(map) || !(map.flags & PROT_READ)) { diff --git a/libbacktrace/BacktraceCurrent.h b/libbacktrace/BacktraceCurrent.h index 072ffd26a..60a9117a9 100644 --- a/libbacktrace/BacktraceCurrent.h +++ b/libbacktrace/BacktraceCurrent.h @@ -40,9 +40,9 @@ class BacktraceCurrent : public Backtrace { BacktraceCurrent(pid_t pid, pid_t tid, BacktraceMap* map) : Backtrace(pid, tid, map) {} virtual ~BacktraceCurrent() {} - size_t Read(uintptr_t addr, uint8_t* buffer, size_t bytes) override; + size_t Read(uint64_t addr, uint8_t* buffer, size_t bytes) override; - bool ReadWord(uintptr_t ptr, word_t* out_value) override; + bool ReadWord(uint64_t ptr, word_t* out_value) override; bool Unwind(size_t num_ignore_frames, ucontext_t* ucontext) override; diff --git a/libbacktrace/BacktraceMap.cpp b/libbacktrace/BacktraceMap.cpp index 0f1ae11f7..2a657b85e 100644 --- a/libbacktrace/BacktraceMap.cpp +++ b/libbacktrace/BacktraceMap.cpp @@ -38,7 +38,7 @@ BacktraceMap::BacktraceMap(pid_t pid) : pid_(pid) { BacktraceMap::~BacktraceMap() { } -void BacktraceMap::FillIn(uintptr_t addr, backtrace_map_t* map) { +void BacktraceMap::FillIn(uint64_t addr, backtrace_map_t* map) { ScopedBacktraceMapIteratorLock lock(this); for (auto it = begin(); it != end(); ++it) { const backtrace_map_t* entry = *it; diff --git a/libbacktrace/BacktraceOffline.cpp b/libbacktrace/BacktraceOffline.cpp index 30845a2d0..a05671651 100644 --- a/libbacktrace/BacktraceOffline.cpp +++ b/libbacktrace/BacktraceOffline.cpp @@ -57,7 +57,7 @@ struct EhFrame { uint64_t hdr_vaddr; uint64_t vaddr; uint64_t fde_table_offset; - uintptr_t min_func_vaddr; + uint64_t min_func_vaddr; std::vector hdr_data; std::vector data; }; @@ -221,8 +221,8 @@ bool BacktraceOffline::Unwind(size_t num_ignore_frames, ucontext_t* context) { frames_.resize(num_frames + 1); backtrace_frame_data_t* frame = &frames_[num_frames]; frame->num = num_frames; - frame->pc = static_cast(pc); - frame->sp = static_cast(sp); + frame->pc = static_cast(pc); + frame->sp = static_cast(sp); frame->stack_size = 0; if (num_frames > 0) { @@ -253,12 +253,12 @@ bool BacktraceOffline::Unwind(size_t num_ignore_frames, ucontext_t* context) { return true; } -bool BacktraceOffline::ReadWord(uintptr_t ptr, word_t* out_value) { +bool BacktraceOffline::ReadWord(uint64_t ptr, word_t* out_value) { size_t bytes_read = Read(ptr, reinterpret_cast(out_value), sizeof(word_t)); return bytes_read == sizeof(word_t); } -size_t BacktraceOffline::Read(uintptr_t addr, uint8_t* buffer, size_t bytes) { +size_t BacktraceOffline::Read(uint64_t addr, uint8_t* buffer, size_t bytes) { // Normally, libunwind needs stack information and call frame information to do remote unwinding. // If call frame information is stored in .debug_frame, libunwind can read it from file // by itself. If call frame information is stored in .eh_frame, we need to provide data in @@ -386,9 +386,8 @@ bool BacktraceOffline::FindProcInfo(unw_addr_space_t addr_space, uint64_t ip, proc_info->start_ip = *it; proc_info->format = UNW_INFO_FORMAT_ARM_EXIDX; proc_info->unwind_info = reinterpret_cast( - static_cast(index * sizeof(ArmIdxEntry) + - debug_frame->arm_exidx.exidx_vaddr + - debug_frame->min_vaddr)); + static_cast(index * sizeof(ArmIdxEntry) + debug_frame->arm_exidx.exidx_vaddr + + debug_frame->min_vaddr)); eh_frame_hdr_space_.Clear(); eh_frame_space_.Clear(); // Prepare arm_exidx space and arm_extab space. @@ -595,7 +594,7 @@ bool BacktraceOffline::ReadReg(size_t reg, uint64_t* value) { return result; } -std::string BacktraceOffline::GetFunctionNameRaw(uintptr_t, uintptr_t* offset) { +std::string BacktraceOffline::GetFunctionNameRaw(uint64_t, uint64_t* offset) { // We don't have enough information to support this. And it is expensive. *offset = 0; return ""; diff --git a/libbacktrace/BacktraceOffline.h b/libbacktrace/BacktraceOffline.h index fcde3796c..e028cd848 100644 --- a/libbacktrace/BacktraceOffline.h +++ b/libbacktrace/BacktraceOffline.h @@ -57,9 +57,9 @@ class BacktraceOffline : public Backtrace { bool Unwind(size_t num_ignore_frames, ucontext_t* context) override; - bool ReadWord(uintptr_t ptr, word_t* out_value) override; + bool ReadWord(uint64_t ptr, word_t* out_value) override; - size_t Read(uintptr_t addr, uint8_t* buffer, size_t bytes) override; + size_t Read(uint64_t addr, uint8_t* buffer, size_t bytes) override; bool FindProcInfo(unw_addr_space_t addr_space, uint64_t ip, unw_proc_info_t* proc_info, int need_unwind_info); @@ -67,7 +67,7 @@ class BacktraceOffline : public Backtrace { bool ReadReg(size_t reg_index, uint64_t* value); protected: - std::string GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) override; + std::string GetFunctionNameRaw(uint64_t pc, uint64_t* offset) override; DebugFrameInfo* GetDebugFrameInFile(const std::string& filename); bool cache_file_; diff --git a/libbacktrace/BacktracePtrace.cpp b/libbacktrace/BacktracePtrace.cpp index fd8b7134f..bf6b16ff0 100644 --- a/libbacktrace/BacktracePtrace.cpp +++ b/libbacktrace/BacktracePtrace.cpp @@ -31,7 +31,7 @@ #include "thread_utils.h" #if !defined(__APPLE__) -static bool PtraceRead(pid_t tid, uintptr_t addr, word_t* out_value) { +static bool PtraceRead(pid_t tid, uint64_t addr, word_t* out_value) { // ptrace() returns -1 and sets errno when the operation fails. // To disambiguate -1 from a valid result, we clear errno beforehand. errno = 0; @@ -43,7 +43,7 @@ static bool PtraceRead(pid_t tid, uintptr_t addr, word_t* out_value) { } #endif -bool BacktracePtrace::ReadWord(uintptr_t ptr, word_t* out_value) { +bool BacktracePtrace::ReadWord(uint64_t ptr, word_t* out_value) { #if defined(__APPLE__) BACK_LOGW("MacOS does not support reading from another pid."); return false; @@ -62,7 +62,7 @@ bool BacktracePtrace::ReadWord(uintptr_t ptr, word_t* out_value) { #endif } -size_t BacktracePtrace::Read(uintptr_t addr, uint8_t* buffer, size_t bytes) { +size_t BacktracePtrace::Read(uint64_t addr, uint8_t* buffer, size_t bytes) { #if defined(__APPLE__) BACK_LOGW("MacOS does not support reading from another pid."); return 0; diff --git a/libbacktrace/BacktracePtrace.h b/libbacktrace/BacktracePtrace.h index d110b488a..1ae3adf55 100644 --- a/libbacktrace/BacktracePtrace.h +++ b/libbacktrace/BacktracePtrace.h @@ -29,9 +29,9 @@ class BacktracePtrace : public Backtrace { BacktracePtrace(pid_t pid, pid_t tid, BacktraceMap* map) : Backtrace(pid, tid, map) {} virtual ~BacktracePtrace() {} - size_t Read(uintptr_t addr, uint8_t* buffer, size_t bytes) override; + size_t Read(uint64_t addr, uint8_t* buffer, size_t bytes) override; - bool ReadWord(uintptr_t ptr, word_t* out_value) override; + bool ReadWord(uint64_t ptr, word_t* out_value) override; }; #endif // _LIBBACKTRACE_BACKTRACE_PTRACE_H diff --git a/libbacktrace/UnwindCurrent.cpp b/libbacktrace/UnwindCurrent.cpp deleted file mode 100644 index 3ccf13c77..000000000 --- a/libbacktrace/UnwindCurrent.cpp +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -#include -#include - -#define UNW_LOCAL_ONLY -#include - -#include -#include - -#include "BacktraceLog.h" -#include "UnwindCurrent.h" - -std::string UnwindCurrent::GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) { - if (!initialized_) { - // If init local is not called, then trying to get a function name will - // fail, so try to initialize first. - std::unique_ptr cursor(new unw_cursor_t); - if (unw_init_local(cursor.get(), &context_) < 0) { - return ""; - } - initialized_ = true; - } - - *offset = 0; - char buf[512]; - unw_word_t value; - if (unw_get_proc_name_by_ip(unw_local_addr_space, pc, buf, sizeof(buf), - &value, &context_) >= 0 && buf[0] != '\0') { - *offset = static_cast(value); - return buf; - } - return ""; -} - -void UnwindCurrent::GetUnwContextFromUcontext(const ucontext_t* ucontext) { - unw_tdep_context_t* unw_context = reinterpret_cast(&context_); - -#if defined(__arm__) - unw_context->regs[0] = ucontext->uc_mcontext.arm_r0; - unw_context->regs[1] = ucontext->uc_mcontext.arm_r1; - unw_context->regs[2] = ucontext->uc_mcontext.arm_r2; - unw_context->regs[3] = ucontext->uc_mcontext.arm_r3; - unw_context->regs[4] = ucontext->uc_mcontext.arm_r4; - unw_context->regs[5] = ucontext->uc_mcontext.arm_r5; - unw_context->regs[6] = ucontext->uc_mcontext.arm_r6; - unw_context->regs[7] = ucontext->uc_mcontext.arm_r7; - unw_context->regs[8] = ucontext->uc_mcontext.arm_r8; - unw_context->regs[9] = ucontext->uc_mcontext.arm_r9; - unw_context->regs[10] = ucontext->uc_mcontext.arm_r10; - unw_context->regs[11] = ucontext->uc_mcontext.arm_fp; - unw_context->regs[12] = ucontext->uc_mcontext.arm_ip; - unw_context->regs[13] = ucontext->uc_mcontext.arm_sp; - unw_context->regs[14] = ucontext->uc_mcontext.arm_lr; - unw_context->regs[15] = ucontext->uc_mcontext.arm_pc; -#else - unw_context->uc_mcontext = ucontext->uc_mcontext; -#endif -} - -bool UnwindCurrent::UnwindFromContext(size_t num_ignore_frames, ucontext_t* ucontext) { - if (ucontext == nullptr) { - int ret = unw_getcontext(&context_); - if (ret < 0) { - BACK_LOGW("unw_getcontext failed %d", ret); - error_.error_code = BACKTRACE_UNWIND_ERROR_SETUP_FAILED; - return false; - } - } else { - GetUnwContextFromUcontext(ucontext); - } - - // The cursor structure is pretty large, do not put it on the stack. - std::unique_ptr cursor(new unw_cursor_t); - int ret = unw_init_local(cursor.get(), &context_); - if (ret < 0) { - BACK_LOGW("unw_init_local failed %d", ret); - error_.error_code = BACKTRACE_UNWIND_ERROR_SETUP_FAILED; - return false; - } - initialized_ = true; - - size_t num_frames = 0; - do { - unw_word_t pc; - ret = unw_get_reg(cursor.get(), UNW_REG_IP, &pc); - if (ret < 0) { - BACK_LOGW("Failed to read IP %d", ret); - break; - } - unw_word_t sp; - ret = unw_get_reg(cursor.get(), UNW_REG_SP, &sp); - if (ret < 0) { - BACK_LOGW("Failed to read SP %d", ret); - break; - } - - frames_.resize(num_frames+1); - backtrace_frame_data_t* frame = &frames_.at(num_frames); - frame->num = num_frames; - frame->pc = static_cast(pc); - frame->sp = static_cast(sp); - frame->stack_size = 0; - - FillInMap(frame->pc, &frame->map); - // Check to see if we should skip this frame because it's coming - // from within the library, and we are doing a local unwind. - if (ucontext != nullptr || num_frames != 0 || !DiscardFrame(*frame)) { - if (num_ignore_frames == 0) { - // GetFunctionName is an expensive call, only do it if we are - // keeping the frame. - frame->func_name = GetFunctionName(frame->pc, &frame->func_offset, &frame->map); - if (num_frames > 0) { - // Set the stack size for the previous frame. - backtrace_frame_data_t* prev = &frames_.at(num_frames-1); - prev->stack_size = frame->sp - prev->sp; - } - if (BacktraceMap::IsValid(frame->map)) { - frame->rel_pc = frame->pc - frame->map.start + frame->map.load_bias; - } else { - frame->rel_pc = frame->pc; - } - num_frames++; - } else { - num_ignore_frames--; - // Set the number of frames to zero to remove the frame added - // above. By definition, if we still have frames to ignore - // there should only be one frame in the vector. - CHECK(num_frames == 0); - frames_.resize(0); - } - } - // If the pc is in a device map, then don't try to step. - if (frame->map.flags & PROT_DEVICE_MAP) { - break; - } - // Verify the sp is not in a device map too. - backtrace_map_t map; - FillInMap(frame->sp, &map); - if (map.flags & PROT_DEVICE_MAP) { - break; - } - ret = unw_step (cursor.get()); - } while (ret > 0 && num_frames < MAX_BACKTRACE_FRAMES); - - return true; -} diff --git a/libbacktrace/UnwindCurrent.h b/libbacktrace/UnwindCurrent.h deleted file mode 100644 index 3656104b0..000000000 --- a/libbacktrace/UnwindCurrent.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _LIBBACKTRACE_UNWIND_CURRENT_H -#define _LIBBACKTRACE_UNWIND_CURRENT_H - -#include -#include -#include - -#include - -#include -#include - -#include "BacktraceCurrent.h" - -#define UNW_LOCAL_ONLY -#include - -class UnwindCurrent : public BacktraceCurrent { - public: - UnwindCurrent(pid_t pid, pid_t tid, BacktraceMap* map) : BacktraceCurrent(pid, tid, map) {} - virtual ~UnwindCurrent() {} - - std::string GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) override; - - private: - void GetUnwContextFromUcontext(const ucontext_t* ucontext); - - bool UnwindFromContext(size_t num_ignore_frames, ucontext_t* ucontext) override; - - unw_context_t context_; - - bool initialized_ = false; -}; - -#endif // _LIBBACKTRACE_UNWIND_CURRENT_H diff --git a/libbacktrace/UnwindMap.cpp b/libbacktrace/UnwindMap.cpp index 3cab0d1b0..798c769c8 100644 --- a/libbacktrace/UnwindMap.cpp +++ b/libbacktrace/UnwindMap.cpp @@ -134,7 +134,7 @@ bool UnwindMapLocal::Build() { return (map_created_ = (unw_map_local_create() == 0)) && GenerateMap();; } -void UnwindMapLocal::FillIn(uintptr_t addr, backtrace_map_t* map) { +void UnwindMapLocal::FillIn(uint64_t addr, backtrace_map_t* map) { BacktraceMap::FillIn(addr, map); if (!IsValid(*map)) { // Check to see if the underlying map changed and regenerate the map diff --git a/libbacktrace/UnwindMap.h b/libbacktrace/UnwindMap.h index 6ffdafd18..15544e82b 100644 --- a/libbacktrace/UnwindMap.h +++ b/libbacktrace/UnwindMap.h @@ -55,7 +55,7 @@ class UnwindMapLocal : public UnwindMap { bool Build() override; - void FillIn(uintptr_t addr, backtrace_map_t* map) override; + void FillIn(uint64_t addr, backtrace_map_t* map) override; void LockIterator() override { pthread_rwlock_rdlock(&map_lock_); } void UnlockIterator() override { pthread_rwlock_unlock(&map_lock_); } diff --git a/libbacktrace/UnwindPtrace.cpp b/libbacktrace/UnwindPtrace.cpp deleted file mode 100644 index 2155b8adc..000000000 --- a/libbacktrace/UnwindPtrace.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include - -#include -#include - -#include -#include - -#include "BacktraceLog.h" -#include "UnwindMap.h" -#include "UnwindPtrace.h" - -UnwindPtrace::UnwindPtrace(pid_t pid, pid_t tid, BacktraceMap* map) - : BacktracePtrace(pid, tid, map), addr_space_(nullptr), upt_info_(nullptr) { -} - -UnwindPtrace::~UnwindPtrace() { - if (upt_info_) { - _UPT_destroy(upt_info_); - upt_info_ = nullptr; - } - - if (addr_space_) { - // Remove the map from the address space before destroying it. - // It will be freed in the UnwindMap destructor. - unw_map_set(addr_space_, nullptr); - - unw_destroy_addr_space(addr_space_); - addr_space_ = nullptr; - } -} - -bool UnwindPtrace::Init() { - if (upt_info_) { - return true; - } - - if (addr_space_) { - // If somehow the addr_space_ gets initialized but upt_info_ doesn't, - // then that indicates there is some kind of failure. - return false; - } - - addr_space_ = unw_create_addr_space(&_UPT_accessors, 0); - if (!addr_space_) { - BACK_LOGW("unw_create_addr_space failed."); - error_.error_code = BACKTRACE_UNWIND_ERROR_SETUP_FAILED; - return false; - } - - UnwindMap* map = static_cast(GetMap()); - unw_map_set(addr_space_, map->GetMapCursor()); - - upt_info_ = reinterpret_cast(_UPT_create(Tid())); - if (!upt_info_) { - BACK_LOGW("Failed to create upt info."); - error_.error_code = BACKTRACE_UNWIND_ERROR_SETUP_FAILED; - return false; - } - - return true; -} - -bool UnwindPtrace::Unwind(size_t num_ignore_frames, ucontext_t* ucontext) { - if (GetMap() == nullptr) { - // Without a map object, we can't do anything. - error_.error_code = BACKTRACE_UNWIND_ERROR_MAP_MISSING; - return false; - } - - error_.error_code = BACKTRACE_UNWIND_NO_ERROR; - - if (ucontext) { - BACK_LOGW("Unwinding from a specified context not supported yet."); - error_.error_code = BACKTRACE_UNWIND_ERROR_UNSUPPORTED_OPERATION; - return false; - } - - if (!Init()) { - return false; - } - - unw_cursor_t cursor; - int ret = unw_init_remote(&cursor, addr_space_, upt_info_); - if (ret < 0) { - BACK_LOGW("unw_init_remote failed %d", ret); - error_.error_code = BACKTRACE_UNWIND_ERROR_SETUP_FAILED; - return false; - } - - size_t num_frames = 0; - do { - unw_word_t pc; - ret = unw_get_reg(&cursor, UNW_REG_IP, &pc); - if (ret < 0) { - BACK_LOGW("Failed to read IP %d", ret); - break; - } - unw_word_t sp; - ret = unw_get_reg(&cursor, UNW_REG_SP, &sp); - if (ret < 0) { - BACK_LOGW("Failed to read SP %d", ret); - break; - } - - if (num_ignore_frames == 0) { - frames_.resize(num_frames+1); - backtrace_frame_data_t* frame = &frames_.at(num_frames); - frame->num = num_frames; - frame->pc = static_cast(pc); - frame->sp = static_cast(sp); - frame->stack_size = 0; - - if (num_frames > 0) { - backtrace_frame_data_t* prev = &frames_.at(num_frames-1); - prev->stack_size = frame->sp - prev->sp; - } - - FillInMap(frame->pc, &frame->map); - if (BacktraceMap::IsValid(frame->map)) { - frame->rel_pc = frame->pc - frame->map.start + frame->map.load_bias; - } else { - frame->rel_pc = frame->pc; - } - - frame->func_name = GetFunctionName(frame->pc, &frame->func_offset, &frame->map); - - num_frames++; - // If the pc is in a device map, then don't try to step. - if (frame->map.flags & PROT_DEVICE_MAP) { - break; - } - } else { - // If the pc is in a device map, then don't try to step. - backtrace_map_t map; - FillInMap(pc, &map); - if (map.flags & PROT_DEVICE_MAP) { - break; - } - num_ignore_frames--; - } - // Verify the sp is not in a device map. - backtrace_map_t map; - FillInMap(sp, &map); - if (map.flags & PROT_DEVICE_MAP) { - break; - } - ret = unw_step (&cursor); - } while (ret > 0 && num_frames < MAX_BACKTRACE_FRAMES); - - return true; -} - -std::string UnwindPtrace::GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) { - if (!Init()) { - return ""; - } - - *offset = 0; - char buf[512]; - unw_word_t value; - if (unw_get_proc_name_by_ip(addr_space_, pc, buf, sizeof(buf), &value, - upt_info_) >= 0 && buf[0] != '\0') { - *offset = static_cast(value); - return buf; - } - return ""; -} diff --git a/libbacktrace/UnwindPtrace.h b/libbacktrace/UnwindPtrace.h deleted file mode 100644 index 46881101f..000000000 --- a/libbacktrace/UnwindPtrace.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _LIBBACKTRACE_UNWIND_PTRACE_H -#define _LIBBACKTRACE_UNWIND_PTRACE_H - -#include -#include - -#include - -#ifdef UNW_LOCAL_ONLY -#undef UNW_LOCAL_ONLY -#endif -#include - -#include "BacktracePtrace.h" - -class UnwindPtrace : public BacktracePtrace { - public: - UnwindPtrace(pid_t pid, pid_t tid, BacktraceMap* map); - virtual ~UnwindPtrace(); - - bool Unwind(size_t num_ignore_frames, ucontext_t* ucontext) override; - - std::string GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) override; - - private: - bool Init(); - - unw_addr_space_t addr_space_; - struct UPT_info* upt_info_; -}; - -#endif // _LIBBACKTRACE_UNWIND_PTRACE_H diff --git a/libbacktrace/UnwindStack.cpp b/libbacktrace/UnwindStack.cpp index b0345a140..441dc8141 100644 --- a/libbacktrace/UnwindStack.cpp +++ b/libbacktrace/UnwindStack.cpp @@ -88,7 +88,7 @@ bool Backtrace::Unwind(unwindstack::Regs* regs, BacktraceMap* back_map, UnwindStackCurrent::UnwindStackCurrent(pid_t pid, pid_t tid, BacktraceMap* map) : BacktraceCurrent(pid, tid, map) {} -std::string UnwindStackCurrent::GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) { +std::string UnwindStackCurrent::GetFunctionNameRaw(uint64_t pc, uint64_t* offset) { return GetMap()->GetFunctionName(pc, offset); } @@ -111,7 +111,7 @@ bool UnwindStackCurrent::UnwindFromContext(size_t num_ignore_frames, ucontext_t* UnwindStackPtrace::UnwindStackPtrace(pid_t pid, pid_t tid, BacktraceMap* map) : BacktracePtrace(pid, tid, map), memory_(pid) {} -std::string UnwindStackPtrace::GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) { +std::string UnwindStackPtrace::GetFunctionNameRaw(uint64_t pc, uint64_t* offset) { return GetMap()->GetFunctionName(pc, offset); } @@ -127,6 +127,6 @@ bool UnwindStackPtrace::Unwind(size_t num_ignore_frames, ucontext_t* context) { return Backtrace::Unwind(regs.get(), GetMap(), &frames_, num_ignore_frames, nullptr); } -size_t UnwindStackPtrace::Read(uintptr_t addr, uint8_t* buffer, size_t bytes) { +size_t UnwindStackPtrace::Read(uint64_t addr, uint8_t* buffer, size_t bytes) { return memory_.Read(addr, buffer, bytes); } diff --git a/libbacktrace/UnwindStack.h b/libbacktrace/UnwindStack.h index ee2a706f7..498ad4ef7 100644 --- a/libbacktrace/UnwindStack.h +++ b/libbacktrace/UnwindStack.h @@ -32,7 +32,7 @@ class UnwindStackCurrent : public BacktraceCurrent { UnwindStackCurrent(pid_t pid, pid_t tid, BacktraceMap* map); virtual ~UnwindStackCurrent() = default; - std::string GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) override; + std::string GetFunctionNameRaw(uint64_t pc, uint64_t* offset) override; bool UnwindFromContext(size_t num_ignore_frames, ucontext_t* ucontext) override; }; @@ -44,9 +44,9 @@ class UnwindStackPtrace : public BacktracePtrace { bool Unwind(size_t num_ignore_frames, ucontext_t* context) override; - std::string GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset); + std::string GetFunctionNameRaw(uint64_t pc, uint64_t* offset); - size_t Read(uintptr_t addr, uint8_t* buffer, size_t bytes) override; + size_t Read(uint64_t addr, uint8_t* buffer, size_t bytes) override; private: unwindstack::MemoryRemote memory_; diff --git a/libbacktrace/UnwindStackMap.cpp b/libbacktrace/UnwindStackMap.cpp index 93406dc62..60c7952a9 100644 --- a/libbacktrace/UnwindStackMap.cpp +++ b/libbacktrace/UnwindStackMap.cpp @@ -57,7 +57,7 @@ bool UnwindStackMap::Build() { map.end = map_info->end; map.offset = map_info->offset; // Set to -1 so that it is demand loaded. - map.load_bias = static_cast(-1); + map.load_bias = static_cast(-1); map.flags = map_info->flags; map.name = map_info->name; @@ -67,9 +67,9 @@ bool UnwindStackMap::Build() { return true; } -void UnwindStackMap::FillIn(uintptr_t addr, backtrace_map_t* map) { +void UnwindStackMap::FillIn(uint64_t addr, backtrace_map_t* map) { BacktraceMap::FillIn(addr, map); - if (map->load_bias != static_cast(-1)) { + if (map->load_bias != static_cast(-1)) { return; } @@ -93,7 +93,7 @@ uint64_t UnwindStackMap::GetLoadBias(size_t index) { return map_info->GetLoadBias(process_memory_); } -std::string UnwindStackMap::GetFunctionName(uintptr_t pc, uintptr_t* offset) { +std::string UnwindStackMap::GetFunctionName(uint64_t pc, uint64_t* offset) { *offset = 0; unwindstack::Maps* maps = stack_maps(); diff --git a/libbacktrace/UnwindStackMap.h b/libbacktrace/UnwindStackMap.h index 12c590982..6b988095c 100644 --- a/libbacktrace/UnwindStackMap.h +++ b/libbacktrace/UnwindStackMap.h @@ -33,9 +33,9 @@ class UnwindStackMap : public BacktraceMap { bool Build() override; - void FillIn(uintptr_t addr, backtrace_map_t* map) override; + void FillIn(uint64_t addr, backtrace_map_t* map) override; - virtual std::string GetFunctionName(uintptr_t pc, uintptr_t* offset) override; + virtual std::string GetFunctionName(uint64_t pc, uint64_t* offset) override; virtual std::shared_ptr GetProcessMemory() override final; unwindstack::Maps* stack_maps() { return stack_maps_.get(); } diff --git a/libbacktrace/backtrace_offline_test.cpp b/libbacktrace/backtrace_offline_test.cpp index e92bc6109..e2a744198 100644 --- a/libbacktrace/backtrace_offline_test.cpp +++ b/libbacktrace/backtrace_offline_test.cpp @@ -75,20 +75,20 @@ static ucontext_t GetUContextFromUnwContext(const unw_context_t& unw_context) { struct FunctionSymbol { std::string name; - uintptr_t start; - uintptr_t end; + uint64_t start; + uint64_t end; }; static std::vector GetFunctionSymbols() { std::vector symbols = { {"unknown_start", 0, 0}, - {"test_level_one", reinterpret_cast(&test_level_one), 0}, - {"test_level_two", reinterpret_cast(&test_level_two), 0}, - {"test_level_three", reinterpret_cast(&test_level_three), 0}, - {"test_level_four", reinterpret_cast(&test_level_four), 0}, - {"test_recursive_call", reinterpret_cast(&test_recursive_call), 0}, - {"test_get_context_and_wait", reinterpret_cast(&test_get_context_and_wait), 0}, - {"unknown_end", static_cast(-1), static_cast(-1)}, + {"test_level_one", reinterpret_cast(&test_level_one), 0}, + {"test_level_two", reinterpret_cast(&test_level_two), 0}, + {"test_level_three", reinterpret_cast(&test_level_three), 0}, + {"test_level_four", reinterpret_cast(&test_level_four), 0}, + {"test_recursive_call", reinterpret_cast(&test_recursive_call), 0}, + {"test_get_context_and_wait", reinterpret_cast(&test_get_context_and_wait), 0}, + {"unknown_end", static_cast(-1), static_cast(-1)}, }; std::sort( symbols.begin(), symbols.end(), @@ -141,7 +141,7 @@ TEST(libbacktrace, DISABLED_generate_offline_testdata) { const size_t stack_size = 16 * 1024; void* stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); ASSERT_NE(MAP_FAILED, stack); - uintptr_t stack_addr = reinterpret_cast(stack); + uint64_t stack_addr = reinterpret_cast(stack); pthread_attr_t attr; ASSERT_EQ(0, pthread_attr_init(&attr)); ASSERT_EQ(0, pthread_attr_setstack(&attr, reinterpret_cast(stack), stack_size)); @@ -174,8 +174,8 @@ TEST(libbacktrace, DISABLED_generate_offline_testdata) { for (auto it = map->begin(); it != map->end(); ++it) { const backtrace_map_t* entry = *it; testdata += - android::base::StringPrintf("map: start: %" PRIxPTR " end: %" PRIxPTR " offset: %" PRIxPTR - " load_bias: %" PRIxPTR " flags: %d name: %s\n", + android::base::StringPrintf("map: start: %" PRIx64 " end: %" PRIx64 " offset: %" PRIx64 + " load_bias: %" PRIx64 " flags: %d name: %s\n", entry->start, entry->end, entry->offset, entry->load_bias, entry->flags, entry->name.c_str()); } @@ -194,9 +194,9 @@ TEST(libbacktrace, DISABLED_generate_offline_testdata) { // 5. Dump function symbols std::vector function_symbols = GetFunctionSymbols(); for (const auto& symbol : function_symbols) { - testdata += android::base::StringPrintf( - "function: start: %" PRIxPTR " end: %" PRIxPTR" name: %s\n", - symbol.start, symbol.end, symbol.name.c_str()); + testdata += + android::base::StringPrintf("function: start: %" PRIx64 " end: %" PRIx64 " name: %s\n", + symbol.start, symbol.end, symbol.name.c_str()); } ASSERT_TRUE(android::base::WriteStringToFile(testdata, "offline_testdata")); @@ -204,7 +204,7 @@ TEST(libbacktrace, DISABLED_generate_offline_testdata) { // Return the name of the function which matches the address. Although we don't know the // exact end of each function, it is accurate enough for the tests. -static std::string FunctionNameForAddress(uintptr_t addr, +static std::string FunctionNameForAddress(uint64_t addr, const std::vector& symbols) { for (auto& symbol : symbols) { if (addr >= symbol.start && addr < symbol.end) { @@ -240,7 +240,7 @@ bool ReadOfflineTestData(const std::string offline_testdata_path, OfflineTestDat backtrace_map_t& map = testdata->maps.back(); int pos; sscanf(line.c_str(), - "map: start: %" SCNxPTR " end: %" SCNxPTR " offset: %" SCNxPTR " load_bias: %" SCNxPTR + "map: start: %" SCNx64 " end: %" SCNx64 " offset: %" SCNx64 " load_bias: %" SCNx64 " flags: %d name: %n", &map.start, &map.end, &map.offset, &map.load_bias, &map.flags, &pos); map.name = android::base::Trim(line.substr(pos)); @@ -302,9 +302,8 @@ bool ReadOfflineTestData(const std::string offline_testdata_path, OfflineTestDat testdata->symbols.resize(testdata->symbols.size() + 1); FunctionSymbol& symbol = testdata->symbols.back(); int pos; - sscanf(line.c_str(), - "function: start: %" SCNxPTR " end: %" SCNxPTR " name: %n", - &symbol.start, &symbol.end, &pos); + sscanf(line.c_str(), "function: start: %" SCNx64 " end: %" SCNx64 " name: %n", &symbol.start, + &symbol.end, &pos); symbol.name = line.substr(pos); } } @@ -342,7 +341,7 @@ static void BacktraceOfflineTest(const char* arch, const std::string& testlib_na ASSERT_TRUE(backtrace->Unwind(0, &ucontext)); // Collect pc values of the call stack frames. - std::vector pc_values; + std::vector pc_values; for (size_t i = 0; i < backtrace->NumFrames(); ++i) { pc_values.push_back(backtrace->GetFrame(i)->pc); } @@ -420,7 +419,7 @@ static void LibUnwindingTest(const std::string& arch, const std::string& testdat ASSERT_EQ(testdata.symbols.size(), backtrace->NumFrames()); for (size_t i = 0; i < backtrace->NumFrames(); ++i) { - uintptr_t vaddr_in_file = + uint64_t vaddr_in_file = backtrace->GetFrame(i)->pc - testdata.maps[0].start + testdata.maps[0].load_bias; std::string name = FunctionNameForAddress(vaddr_in_file, testdata.symbols); ASSERT_EQ(name, testdata.symbols[i].name); diff --git a/libbacktrace/backtrace_test.cpp b/libbacktrace/backtrace_test.cpp index 57b755318..10152f7ad 100644 --- a/libbacktrace/backtrace_test.cpp +++ b/libbacktrace/backtrace_test.cpp @@ -745,8 +745,8 @@ TEST(libbacktrace, fillin_erases) { delete back_map; ASSERT_FALSE(BacktraceMap::IsValid(map)); - ASSERT_EQ(static_cast(0), map.start); - ASSERT_EQ(static_cast(0), map.end); + ASSERT_EQ(static_cast(0), map.start); + ASSERT_EQ(static_cast(0), map.end); ASSERT_EQ(0, map.flags); ASSERT_EQ("", map.name); } @@ -851,8 +851,8 @@ TEST(libbacktrace, format_test) { } struct map_test_t { - uintptr_t start; - uintptr_t end; + uint64_t start; + uint64_t end; }; static bool map_sort(map_test_t i, map_test_t j) { return i.start < j.start; } @@ -863,7 +863,7 @@ static std::string GetTestMapsAsString(const std::vector& maps) { } std::string map_txt; for (auto map : maps) { - map_txt += android::base::StringPrintf("%" PRIxPTR "-%" PRIxPTR "\n", map.start, map.end); + map_txt += android::base::StringPrintf("%" PRIx64 "-%" PRIx64 "\n", map.start, map.end); } return map_txt; } @@ -875,7 +875,7 @@ static std::string GetMapsAsString(BacktraceMap* maps) { std::string map_txt; for (const backtrace_map_t* map : *maps) { map_txt += android::base::StringPrintf( - "%" PRIxPTR "-%" PRIxPTR " flags: 0x%x offset: 0x%" PRIxPTR " load_bias: 0x%" PRIxPTR, + "%" PRIx64 "-%" PRIx64 " flags: 0x%x offset: 0x%" PRIx64 " load_bias: 0x%" PRIx64, map->start, map->end, map->flags, map->offset, map->load_bias); if (!map->name.empty()) { map_txt += ' ' + map->name; @@ -894,7 +894,7 @@ static void VerifyMap(pid_t pid) { std::vector test_maps; while (fgets(buffer, sizeof(buffer), map_file)) { map_test_t map; - ASSERT_EQ(2, sscanf(buffer, "%" SCNxPTR "-%" SCNxPTR " ", &map.start, &map.end)); + ASSERT_EQ(2, sscanf(buffer, "%" SCNx64 "-%" SCNx64 " ", &map.start, &map.end)); test_maps.push_back(map); } fclose(map_file); @@ -984,7 +984,7 @@ static void* ThreadReadTest(void* data) { return nullptr; } -static void RunReadTest(Backtrace* backtrace, uintptr_t read_addr) { +static void RunReadTest(Backtrace* backtrace, uint64_t read_addr) { size_t pagesize = static_cast(sysconf(_SC_PAGE_SIZE)); // Create a page of data to use to do quick compares. @@ -1035,15 +1035,15 @@ TEST(libbacktrace, thread_read) { std::unique_ptr backtrace(Backtrace::Create(getpid(), thread_data.tid)); ASSERT_TRUE(backtrace.get() != nullptr); - RunReadTest(backtrace.get(), reinterpret_cast(thread_data.data)); + RunReadTest(backtrace.get(), reinterpret_cast(thread_data.data)); android_atomic_acquire_store(0, &thread_data.state); ASSERT_TRUE(WaitForNonZero(&thread_data.state, 10)); } -volatile uintptr_t g_ready = 0; -volatile uintptr_t g_addr = 0; +volatile uint64_t g_ready = 0; +volatile uint64_t g_addr = 0; static void ForkedReadTest() { // Create two map pages. @@ -1063,7 +1063,7 @@ static void ForkedReadTest() { // Set up a simple pattern in memory. InitMemory(memory, pagesize); - g_addr = reinterpret_cast(memory); + g_addr = reinterpret_cast(memory); g_ready = 1; while (1) { @@ -1089,17 +1089,15 @@ TEST(libbacktrace, process_read) { std::unique_ptr backtrace(Backtrace::Create(pid, pid)); ASSERT_TRUE(backtrace.get() != nullptr); - uintptr_t read_addr; - size_t bytes_read = backtrace->Read(reinterpret_cast(&g_ready), - reinterpret_cast(&read_addr), - sizeof(uintptr_t)); - ASSERT_EQ(sizeof(uintptr_t), bytes_read); + uint64_t read_addr; + size_t bytes_read = backtrace->Read(reinterpret_cast(&g_ready), + reinterpret_cast(&read_addr), sizeof(uint64_t)); + ASSERT_EQ(sizeof(uint64_t), bytes_read); if (read_addr) { // The forked process is ready to be read. - bytes_read = backtrace->Read(reinterpret_cast(&g_addr), - reinterpret_cast(&read_addr), - sizeof(uintptr_t)); - ASSERT_EQ(sizeof(uintptr_t), bytes_read); + bytes_read = backtrace->Read(reinterpret_cast(&g_addr), + reinterpret_cast(&read_addr), sizeof(uint64_t)); + ASSERT_EQ(sizeof(uint64_t), bytes_read); RunReadTest(backtrace.get(), read_addr); @@ -1173,7 +1171,7 @@ TEST(libbacktrace, check_unreadable_elf_local) { struct stat buf; ASSERT_TRUE(stat(tmp_so_name, &buf) != -1); - uintptr_t map_size = buf.st_size; + uint64_t map_size = buf.st_size; int fd = open(tmp_so_name, O_RDONLY); ASSERT_TRUE(fd != -1); @@ -1192,11 +1190,10 @@ TEST(libbacktrace, check_unreadable_elf_local) { backtrace->Unwind(0); // Loop through the entire map, and get every function we can find. - map_size += reinterpret_cast(map); + map_size += reinterpret_cast(map); std::string last_func; - for (uintptr_t read_addr = reinterpret_cast(map); - read_addr < map_size; read_addr += 4) { - uintptr_t offset; + for (uint64_t read_addr = reinterpret_cast(map); read_addr < map_size; read_addr += 4) { + uint64_t offset; std::string func_name = backtrace->GetFunctionName(read_addr, &offset); if (!func_name.empty() && last_func != func_name) { found_functions.push_back(func_name); @@ -1204,7 +1201,7 @@ TEST(libbacktrace, check_unreadable_elf_local) { last_func = func_name; } - ASSERT_TRUE(munmap(map, map_size - reinterpret_cast(map)) == 0); + ASSERT_TRUE(munmap(map, map_size - reinterpret_cast(map)) == 0); VerifyFunctionsFound(found_functions); } @@ -1217,7 +1214,7 @@ TEST(libbacktrace, check_unreadable_elf_remote) { struct stat buf; ASSERT_TRUE(stat(tmp_so_name, &buf) != -1); - uintptr_t map_size = buf.st_size; + uint64_t map_size = buf.st_size; pid_t pid; if ((pid = fork()) == 0) { @@ -1240,7 +1237,7 @@ TEST(libbacktrace, check_unreadable_elf_remote) { exit(0); } - g_addr = reinterpret_cast(map); + g_addr = reinterpret_cast(map); g_ready = 1; while (true) { usleep(US_PER_MSEC); @@ -1260,10 +1257,14 @@ TEST(libbacktrace, check_unreadable_elf_remote) { std::unique_ptr backtrace(Backtrace::Create(pid, BACKTRACE_CURRENT_THREAD)); ASSERT_TRUE(backtrace.get() != nullptr); - uintptr_t read_addr; - ASSERT_EQ(sizeof(uintptr_t), backtrace->Read(reinterpret_cast(&g_ready), reinterpret_cast(&read_addr), sizeof(uintptr_t))); + uint64_t read_addr; + ASSERT_EQ(sizeof(uint64_t), + backtrace->Read(reinterpret_cast(&g_ready), + reinterpret_cast(&read_addr), sizeof(uint64_t))); if (read_addr) { - ASSERT_EQ(sizeof(uintptr_t), backtrace->Read(reinterpret_cast(&g_addr), reinterpret_cast(&read_addr), sizeof(uintptr_t))); + ASSERT_EQ(sizeof(uint64_t), + backtrace->Read(reinterpret_cast(&g_addr), + reinterpret_cast(&read_addr), sizeof(uint64_t))); // Needed before GetFunctionName will work. backtrace->Unwind(0); @@ -1272,7 +1273,7 @@ TEST(libbacktrace, check_unreadable_elf_remote) { map_size += read_addr; std::string last_func; for (; read_addr < map_size; read_addr += 4) { - uintptr_t offset; + uint64_t offset; std::string func_name = backtrace->GetFunctionName(read_addr, &offset); if (!func_name.empty() && last_func != func_name) { found_functions.push_back(func_name); @@ -1295,7 +1296,7 @@ TEST(libbacktrace, check_unreadable_elf_remote) { VerifyFunctionsFound(found_functions); } -static bool FindFuncFrameInBacktrace(Backtrace* backtrace, uintptr_t test_func, size_t* frame_num) { +static bool FindFuncFrameInBacktrace(Backtrace* backtrace, uint64_t test_func, size_t* frame_num) { backtrace_map_t map; backtrace->FillInMap(test_func, &map); if (!BacktraceMap::IsValid(map)) { @@ -1314,7 +1315,7 @@ static bool FindFuncFrameInBacktrace(Backtrace* backtrace, uintptr_t test_func, return false; } -static void VerifyUnreadableElfFrame(Backtrace* backtrace, uintptr_t test_func, size_t frame_num) { +static void VerifyUnreadableElfFrame(Backtrace* backtrace, uint64_t test_func, size_t frame_num) { ASSERT_LT(backtrace->NumFrames(), static_cast(MAX_BACKTRACE_FRAMES)) << DumpFrames(backtrace); @@ -1322,11 +1323,12 @@ static void VerifyUnreadableElfFrame(Backtrace* backtrace, uintptr_t test_func, // Make sure that there is at least one more frame above the test func call. ASSERT_LT(frame_num, backtrace->NumFrames()) << DumpFrames(backtrace); - uintptr_t diff = backtrace->GetFrame(frame_num)->pc - test_func; + uint64_t diff = backtrace->GetFrame(frame_num)->pc - test_func; ASSERT_LT(diff, 200U) << DumpFrames(backtrace); } -static void VerifyUnreadableElfBacktrace(uintptr_t test_func) { +static void VerifyUnreadableElfBacktrace(void* func) { + uint64_t test_func = reinterpret_cast(func); std::unique_ptr backtrace(Backtrace::Create(BACKTRACE_CURRENT_PROCESS, BACKTRACE_CURRENT_THREAD)); ASSERT_TRUE(backtrace.get() != nullptr); @@ -1339,7 +1341,7 @@ static void VerifyUnreadableElfBacktrace(uintptr_t test_func) { VerifyUnreadableElfFrame(backtrace.get(), test_func, frame_num); } -typedef int (*test_func_t)(int, int, int, int, void (*)(uintptr_t), uintptr_t); +typedef int (*test_func_t)(int, int, int, int, void (*)(void*), void*); TEST(libbacktrace, unwind_through_unreadable_elf_local) { const char* tmp_so_name = CopySharedLibrary(); @@ -1352,8 +1354,8 @@ TEST(libbacktrace, unwind_through_unreadable_elf_local) { test_func = reinterpret_cast(dlsym(lib_handle, "test_level_one")); ASSERT_TRUE(test_func != nullptr); - ASSERT_NE(test_func(1, 2, 3, 4, VerifyUnreadableElfBacktrace, - reinterpret_cast(test_func)), 0); + ASSERT_NE(test_func(1, 2, 3, 4, VerifyUnreadableElfBacktrace, reinterpret_cast(test_func)), + 0); ASSERT_TRUE(dlclose(lib_handle) == 0); } @@ -1391,10 +1393,9 @@ TEST(libbacktrace, unwind_through_unreadable_elf_remote) { ASSERT_EQ(BACKTRACE_UNWIND_NO_ERROR, backtrace->GetError().error_code); size_t frame_num; - if (FindFuncFrameInBacktrace(backtrace.get(), - reinterpret_cast(test_func), &frame_num)) { - - VerifyUnreadableElfFrame(backtrace.get(), reinterpret_cast(test_func), frame_num); + if (FindFuncFrameInBacktrace(backtrace.get(), reinterpret_cast(test_func), + &frame_num)) { + VerifyUnreadableElfFrame(backtrace.get(), reinterpret_cast(test_func), frame_num); done = true; } @@ -1426,8 +1427,8 @@ TEST(libbacktrace, local_get_function_name_before_unwind) { ASSERT_TRUE(backtrace.get() != nullptr); // Verify that trying to get a function name before doing an unwind works. - uintptr_t cur_func_offset = reinterpret_cast(&test_level_one) + 1; - size_t offset; + uint64_t cur_func_offset = reinterpret_cast(&test_level_one) + 1; + uint64_t offset; ASSERT_NE(std::string(""), backtrace->GetFunctionName(cur_func_offset, &offset)); } @@ -1439,14 +1440,14 @@ TEST(libbacktrace, remote_get_function_name_before_unwind) { std::unique_ptr backtrace(Backtrace::Create(pid, pid)); // Verify that trying to get a function name before doing an unwind works. - uintptr_t cur_func_offset = reinterpret_cast(&test_level_one) + 1; - size_t offset; + uint64_t cur_func_offset = reinterpret_cast(&test_level_one) + 1; + uint64_t offset; ASSERT_NE(std::string(""), backtrace->GetFunctionName(cur_func_offset, &offset)); FinishRemoteProcess(pid); } -static void SetUcontextSp(uintptr_t sp, ucontext_t* ucontext) { +static void SetUcontextSp(uint64_t sp, ucontext_t* ucontext) { #if defined(__arm__) ucontext->uc_mcontext.arm_sp = sp; #elif defined(__aarch64__) @@ -1462,7 +1463,7 @@ static void SetUcontextSp(uintptr_t sp, ucontext_t* ucontext) { #endif } -static void SetUcontextPc(uintptr_t pc, ucontext_t* ucontext) { +static void SetUcontextPc(uint64_t pc, ucontext_t* ucontext) { #if defined(__arm__) ucontext->uc_mcontext.arm_pc = pc; #elif defined(__aarch64__) @@ -1478,7 +1479,7 @@ static void SetUcontextPc(uintptr_t pc, ucontext_t* ucontext) { #endif } -static void SetUcontextLr(uintptr_t lr, ucontext_t* ucontext) { +static void SetUcontextLr(uint64_t lr, ucontext_t* ucontext) { #if defined(__arm__) ucontext->uc_mcontext.arm_lr = lr; #elif defined(__aarch64__) @@ -1513,7 +1514,7 @@ static void SetupDeviceMap(void** device_map) { } static void UnwindFromDevice(Backtrace* backtrace, void* device_map) { - uintptr_t device_map_uint = reinterpret_cast(device_map); + uint64_t device_map_uint = reinterpret_cast(device_map); backtrace_map_t map; backtrace->FillInMap(device_map_uint, &map); @@ -1521,12 +1522,12 @@ static void UnwindFromDevice(Backtrace* backtrace, void* device_map) { ASSERT_EQ(PROT_DEVICE_MAP, map.flags & PROT_DEVICE_MAP); // Quick sanity checks. - size_t offset; + uint64_t offset; ASSERT_EQ(std::string(""), backtrace->GetFunctionName(device_map_uint, &offset)); ASSERT_EQ(std::string(""), backtrace->GetFunctionName(device_map_uint, &offset, &map)); ASSERT_EQ(std::string(""), backtrace->GetFunctionName(0, &offset)); - uintptr_t cur_func_offset = reinterpret_cast(&test_level_one) + 1; + uint64_t cur_func_offset = reinterpret_cast(&test_level_one) + 1; // Now verify the device map flag actually causes the function name to be empty. backtrace->FillInMap(cur_func_offset, &map); ASSERT_TRUE((map.flags & PROT_DEVICE_MAP) == 0); @@ -1539,7 +1540,7 @@ static void UnwindFromDevice(Backtrace* backtrace, void* device_map) { // Create a context that has the pc in the device map, but the sp // in a non-device map. memset(&ucontext, 0, sizeof(ucontext)); - SetUcontextSp(reinterpret_cast(&ucontext), &ucontext); + SetUcontextSp(reinterpret_cast(&ucontext), &ucontext); SetUcontextPc(device_map_uint, &ucontext); SetUcontextLr(cur_func_offset, &ucontext); @@ -1549,7 +1550,7 @@ static void UnwindFromDevice(Backtrace* backtrace, void* device_map) { ASSERT_EQ(1U, backtrace->NumFrames()); const backtrace_frame_data_t* frame = backtrace->GetFrame(0); ASSERT_EQ(device_map_uint, frame->pc); - ASSERT_EQ(reinterpret_cast(&ucontext), frame->sp); + ASSERT_EQ(reinterpret_cast(&ucontext), frame->sp); // Check what happens when skipping the first frame. ASSERT_TRUE(backtrace->Unwind(1, &ucontext)); @@ -1669,7 +1670,7 @@ static void UnwindThroughSignal(bool use_action, create_func_t create_func, std::unique_ptr map(map_create_func(pid, false)); std::unique_ptr backtrace(create_func(pid, pid, map.get())); - size_t bytes_read = backtrace->Read(reinterpret_cast(const_cast(&value)), + size_t bytes_read = backtrace->Read(reinterpret_cast(const_cast(&value)), reinterpret_cast(&read_value), sizeof(read_value)); ASSERT_EQ(sizeof(read_value), bytes_read); diff --git a/libbacktrace/include/backtrace/Backtrace.h b/libbacktrace/include/backtrace/Backtrace.h index 592266429..18e9f61e8 100644 --- a/libbacktrace/include/backtrace/Backtrace.h +++ b/libbacktrace/include/backtrace/Backtrace.h @@ -26,11 +26,11 @@ #include #include -#if __LP64__ -#define PRIPTR "016" PRIxPTR +#if defined(__LP64__) +#define PRIPTR "016" PRIx64 typedef uint64_t word_t; #else -#define PRIPTR "08" PRIxPTR +#define PRIPTR "08" PRIx64 typedef uint32_t word_t; #endif @@ -77,13 +77,14 @@ struct BacktraceUnwindError { struct backtrace_frame_data_t { size_t num; // The current fame number. - uintptr_t pc; // The absolute pc. - uintptr_t rel_pc; // The relative pc. - uintptr_t sp; // The top of the stack. + uint64_t pc; // The absolute pc. + uint64_t rel_pc; // The relative pc. + uint64_t sp; // The top of the stack. size_t stack_size; // The size of the stack, zero indicate an unknown stack size. backtrace_map_t map; // The map associated with the given pc. std::string func_name; // The function name associated with this pc, NULL if not found. - uintptr_t func_offset; // pc relative to the start of the function, only valid if func_name is not NULL. + uint64_t func_offset; // pc relative to the start of the function, only valid if func_name is not + // NULL. }; #if defined(__APPLE__) @@ -138,20 +139,20 @@ public: // Get the function name and offset into the function given the pc. // If the string is empty, then no valid function name was found, // or the pc is not in any valid map. - virtual std::string GetFunctionName(uintptr_t pc, uintptr_t* offset, + virtual std::string GetFunctionName(uint64_t pc, uint64_t* offset, const backtrace_map_t* map = NULL); // Fill in the map data associated with the given pc. - virtual void FillInMap(uintptr_t pc, backtrace_map_t* map); + virtual void FillInMap(uint64_t pc, backtrace_map_t* map); // Read the data at a specific address. - virtual bool ReadWord(uintptr_t ptr, word_t* out_value) = 0; + virtual bool ReadWord(uint64_t ptr, word_t* out_value) = 0; // Read arbitrary data from a specific address. If a read request would // span from one map to another, this call only reads up until the end // of the current map. // Returns the total number of bytes actually read. - virtual size_t Read(uintptr_t addr, uint8_t* buffer, size_t bytes) = 0; + virtual size_t Read(uint64_t addr, uint8_t* buffer, size_t bytes) = 0; // Create a string representing the formatted line of backtrace information // for a single frame. @@ -188,9 +189,9 @@ protected: // The name returned is not demangled, GetFunctionName() takes care of // demangling the name. - virtual std::string GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) = 0; + virtual std::string GetFunctionNameRaw(uint64_t pc, uint64_t* offset) = 0; - virtual bool VerifyReadWordArgs(uintptr_t ptr, word_t* out_value); + virtual bool VerifyReadWordArgs(uint64_t ptr, word_t* out_value); bool BuildMap(); diff --git a/libbacktrace/include/backtrace/BacktraceMap.h b/libbacktrace/include/backtrace/BacktraceMap.h index 4ae68dde0..4d020e6ad 100644 --- a/libbacktrace/include/backtrace/BacktraceMap.h +++ b/libbacktrace/include/backtrace/BacktraceMap.h @@ -39,10 +39,10 @@ static constexpr int PROT_DEVICE_MAP = 0x8000; struct backtrace_map_t { - uintptr_t start = 0; - uintptr_t end = 0; - uintptr_t offset = 0; - uintptr_t load_bias = 0; + uint64_t start = 0; + uint64_t end = 0; + uint64_t offset = 0; + uint64_t load_bias = 0; int flags = 0; std::string name; }; @@ -91,7 +91,7 @@ public: return nullptr; } backtrace_map_t* map = &map_->maps_[index_]; - if (map->load_bias == static_cast(-1)) { + if (map->load_bias == static_cast(-1)) { map->load_bias = map_->GetLoadBias(index_); } return map; @@ -106,15 +106,15 @@ public: iterator end() { return iterator(this, maps_.size()); } // Fill in the map data structure for the given address. - virtual void FillIn(uintptr_t addr, backtrace_map_t* map); + virtual void FillIn(uint64_t addr, backtrace_map_t* map); // Only supported with the new unwinder. - virtual std::string GetFunctionName(uintptr_t /*pc*/, uintptr_t* /*offset*/) { return ""; } + virtual std::string GetFunctionName(uint64_t /*pc*/, uint64_t* /*offset*/) { return ""; } virtual std::shared_ptr GetProcessMemory() { return nullptr; } // The flags returned are the same flags as used by the mmap call. // The values are PROT_*. - int GetFlags(uintptr_t pc) { + int GetFlags(uint64_t pc) { backtrace_map_t map; FillIn(pc, &map); if (IsValid(map)) { @@ -123,9 +123,9 @@ public: return PROT_NONE; } - bool IsReadable(uintptr_t pc) { return GetFlags(pc) & PROT_READ; } - bool IsWritable(uintptr_t pc) { return GetFlags(pc) & PROT_WRITE; } - bool IsExecutable(uintptr_t pc) { return GetFlags(pc) & PROT_EXEC; } + bool IsReadable(uint64_t pc) { return GetFlags(pc) & PROT_READ; } + bool IsWritable(uint64_t pc) { return GetFlags(pc) & PROT_WRITE; } + bool IsExecutable(uint64_t pc) { return GetFlags(pc) & PROT_EXEC; } // In order to use the iterators on this object, a caller must // call the LockIterator and UnlockIterator function to guarantee -- cgit v1.2.3