diff options
author | Christopher Ferris <cferris@google.com> | 2018-01-19 23:30:33 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2018-01-19 23:30:33 +0000 |
commit | e20b4a48fee974901e73039f6add426df857e3de (patch) | |
tree | 8818fbffe638b0523535829829e047a6ca0ec82b /libbacktrace | |
parent | b6d7f2655d19f8de30b3957a12715afddf7fc522 (diff) | |
parent | 7937a36c8e24ef2dc5105a2a6b67f395934b2e2f (diff) | |
download | system_core-e20b4a48fee974901e73039f6add426df857e3de.tar.gz system_core-e20b4a48fee974901e73039f6add426df857e3de.tar.bz2 system_core-e20b4a48fee974901e73039f6add426df857e3de.zip |
Merge "Change all uintptr_t to uint64_t in API."
Diffstat (limited to 'libbacktrace')
-rw-r--r-- | libbacktrace/Android.bp | 3 | ||||
-rw-r--r-- | libbacktrace/Backtrace.cpp | 12 | ||||
-rw-r--r-- | libbacktrace/BacktraceCurrent.cpp | 4 | ||||
-rw-r--r-- | libbacktrace/BacktraceCurrent.h | 4 | ||||
-rw-r--r-- | libbacktrace/BacktraceMap.cpp | 2 | ||||
-rw-r--r-- | libbacktrace/BacktraceOffline.cpp | 17 | ||||
-rw-r--r-- | libbacktrace/BacktraceOffline.h | 6 | ||||
-rw-r--r-- | libbacktrace/BacktracePtrace.cpp | 6 | ||||
-rw-r--r-- | libbacktrace/BacktracePtrace.h | 4 | ||||
-rw-r--r-- | libbacktrace/UnwindCurrent.cpp | 165 | ||||
-rw-r--r-- | libbacktrace/UnwindCurrent.h | 51 | ||||
-rw-r--r-- | libbacktrace/UnwindMap.cpp | 2 | ||||
-rw-r--r-- | libbacktrace/UnwindMap.h | 2 | ||||
-rw-r--r-- | libbacktrace/UnwindPtrace.cpp | 186 | ||||
-rw-r--r-- | libbacktrace/UnwindPtrace.h | 48 | ||||
-rw-r--r-- | libbacktrace/UnwindStack.cpp | 6 | ||||
-rw-r--r-- | libbacktrace/UnwindStack.h | 6 | ||||
-rw-r--r-- | libbacktrace/UnwindStackMap.cpp | 8 | ||||
-rw-r--r-- | libbacktrace/UnwindStackMap.h | 4 | ||||
-rw-r--r-- | libbacktrace/backtrace_offline_test.cpp | 43 | ||||
-rw-r--r-- | libbacktrace/backtrace_test.cpp | 115 | ||||
-rw-r--r-- | libbacktrace/include/backtrace/Backtrace.h | 27 | ||||
-rw-r--r-- | libbacktrace/include/backtrace/BacktraceMap.h | 22 |
23 files changed, 144 insertions, 599 deletions
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 <demangle.h> #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<void*>(ptr)); *out_value = static_cast<word_t>(-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<uint8_t> hdr_data; std::vector<uint8_t> 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<uintptr_t>(pc); - frame->sp = static_cast<uintptr_t>(sp); + frame->pc = static_cast<uint64_t>(pc); + frame->sp = static_cast<uint64_t>(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<uint8_t*>(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<void*>( - static_cast<uintptr_t>(index * sizeof(ArmIdxEntry) + - debug_frame->arm_exidx.exidx_vaddr + - debug_frame->min_vaddr)); + static_cast<uint64_t>(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 <stdint.h> -#include <ucontext.h> - -#include <memory> -#include <string> - -#define UNW_LOCAL_ONLY -#include <libunwind.h> - -#include <android-base/logging.h> -#include <backtrace/Backtrace.h> - -#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<unw_cursor_t> 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<uintptr_t>(value); - return buf; - } - return ""; -} - -void UnwindCurrent::GetUnwContextFromUcontext(const ucontext_t* ucontext) { - unw_tdep_context_t* unw_context = reinterpret_cast<unw_tdep_context_t*>(&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<unw_cursor_t> 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<uintptr_t>(pc); - frame->sp = static_cast<uintptr_t>(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 <stdint.h> -#include <sys/types.h> -#include <ucontext.h> - -#include <string> - -#include <backtrace/Backtrace.h> -#include <backtrace/BacktraceMap.h> - -#include "BacktraceCurrent.h" - -#define UNW_LOCAL_ONLY -#include <libunwind.h> - -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 <stdint.h> -#include <sys/types.h> -#include <ucontext.h> - -#include <libunwind.h> -#include <libunwind-ptrace.h> - -#include <backtrace/Backtrace.h> -#include <backtrace/BacktraceMap.h> - -#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<UnwindMap*>(GetMap()); - unw_map_set(addr_space_, map->GetMapCursor()); - - upt_info_ = reinterpret_cast<struct UPT_info*>(_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<uintptr_t>(pc); - frame->sp = static_cast<uintptr_t>(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<uintptr_t>(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 <stdint.h> -#include <sys/types.h> - -#include <string> - -#ifdef UNW_LOCAL_ONLY -#undef UNW_LOCAL_ONLY -#endif -#include <libunwind.h> - -#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 b62ee1659..bbfbddaa8 100644 --- a/libbacktrace/UnwindStack.cpp +++ b/libbacktrace/UnwindStack.cpp @@ -89,7 +89,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); } @@ -112,7 +112,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); } @@ -128,6 +128,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<uintptr_t>(-1); + map.load_bias = static_cast<uint64_t>(-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<uintptr_t>(-1)) { + if (map->load_bias != static_cast<uint64_t>(-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<unwindstack::Memory> 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<FunctionSymbol> GetFunctionSymbols() { std::vector<FunctionSymbol> symbols = { {"unknown_start", 0, 0}, - {"test_level_one", reinterpret_cast<uintptr_t>(&test_level_one), 0}, - {"test_level_two", reinterpret_cast<uintptr_t>(&test_level_two), 0}, - {"test_level_three", reinterpret_cast<uintptr_t>(&test_level_three), 0}, - {"test_level_four", reinterpret_cast<uintptr_t>(&test_level_four), 0}, - {"test_recursive_call", reinterpret_cast<uintptr_t>(&test_recursive_call), 0}, - {"test_get_context_and_wait", reinterpret_cast<uintptr_t>(&test_get_context_and_wait), 0}, - {"unknown_end", static_cast<uintptr_t>(-1), static_cast<uintptr_t>(-1)}, + {"test_level_one", reinterpret_cast<uint64_t>(&test_level_one), 0}, + {"test_level_two", reinterpret_cast<uint64_t>(&test_level_two), 0}, + {"test_level_three", reinterpret_cast<uint64_t>(&test_level_three), 0}, + {"test_level_four", reinterpret_cast<uint64_t>(&test_level_four), 0}, + {"test_recursive_call", reinterpret_cast<uint64_t>(&test_recursive_call), 0}, + {"test_get_context_and_wait", reinterpret_cast<uint64_t>(&test_get_context_and_wait), 0}, + {"unknown_end", static_cast<uint64_t>(-1), static_cast<uint64_t>(-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<uintptr_t>(stack); + uint64_t stack_addr = reinterpret_cast<uint64_t>(stack); pthread_attr_t attr; ASSERT_EQ(0, pthread_attr_init(&attr)); ASSERT_EQ(0, pthread_attr_setstack(&attr, reinterpret_cast<void*>(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<FunctionSymbol> 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<FunctionSymbol>& 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<uintptr_t> pc_values; + std::vector<uint64_t> 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<uintptr_t>(0), map.start); - ASSERT_EQ(static_cast<uintptr_t>(0), map.end); + ASSERT_EQ(static_cast<uint64_t>(0), map.start); + ASSERT_EQ(static_cast<uint64_t>(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<map_test_t>& 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<map_test_t> 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<size_t>(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(Backtrace::Create(getpid(), thread_data.tid)); ASSERT_TRUE(backtrace.get() != nullptr); - RunReadTest(backtrace.get(), reinterpret_cast<uintptr_t>(thread_data.data)); + RunReadTest(backtrace.get(), reinterpret_cast<uint64_t>(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<uintptr_t>(memory); + g_addr = reinterpret_cast<uint64_t>(memory); g_ready = 1; while (1) { @@ -1089,17 +1089,15 @@ TEST(libbacktrace, process_read) { std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, pid)); ASSERT_TRUE(backtrace.get() != nullptr); - uintptr_t read_addr; - size_t bytes_read = backtrace->Read(reinterpret_cast<uintptr_t>(&g_ready), - reinterpret_cast<uint8_t*>(&read_addr), - sizeof(uintptr_t)); - ASSERT_EQ(sizeof(uintptr_t), bytes_read); + uint64_t read_addr; + size_t bytes_read = backtrace->Read(reinterpret_cast<uint64_t>(&g_ready), + reinterpret_cast<uint8_t*>(&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<uintptr_t>(&g_addr), - reinterpret_cast<uint8_t*>(&read_addr), - sizeof(uintptr_t)); - ASSERT_EQ(sizeof(uintptr_t), bytes_read); + bytes_read = backtrace->Read(reinterpret_cast<uint64_t>(&g_addr), + reinterpret_cast<uint8_t*>(&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<uintptr_t>(map); + map_size += reinterpret_cast<uint64_t>(map); std::string last_func; - for (uintptr_t read_addr = reinterpret_cast<uintptr_t>(map); - read_addr < map_size; read_addr += 4) { - uintptr_t offset; + for (uint64_t read_addr = reinterpret_cast<uint64_t>(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<uintptr_t>(map)) == 0); + ASSERT_TRUE(munmap(map, map_size - reinterpret_cast<uint64_t>(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<uintptr_t>(map); + g_addr = reinterpret_cast<uint64_t>(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(Backtrace::Create(pid, BACKTRACE_CURRENT_THREAD)); ASSERT_TRUE(backtrace.get() != nullptr); - uintptr_t read_addr; - ASSERT_EQ(sizeof(uintptr_t), backtrace->Read(reinterpret_cast<uintptr_t>(&g_ready), reinterpret_cast<uint8_t*>(&read_addr), sizeof(uintptr_t))); + uint64_t read_addr; + ASSERT_EQ(sizeof(uint64_t), + backtrace->Read(reinterpret_cast<uint64_t>(&g_ready), + reinterpret_cast<uint8_t*>(&read_addr), sizeof(uint64_t))); if (read_addr) { - ASSERT_EQ(sizeof(uintptr_t), backtrace->Read(reinterpret_cast<uintptr_t>(&g_addr), reinterpret_cast<uint8_t*>(&read_addr), sizeof(uintptr_t))); + ASSERT_EQ(sizeof(uint64_t), + backtrace->Read(reinterpret_cast<uint64_t>(&g_addr), + reinterpret_cast<uint8_t*>(&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<size_t>(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<uint64_t>(func); std::unique_ptr<Backtrace> 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<test_func_t>(dlsym(lib_handle, "test_level_one")); ASSERT_TRUE(test_func != nullptr); - ASSERT_NE(test_func(1, 2, 3, 4, VerifyUnreadableElfBacktrace, - reinterpret_cast<uintptr_t>(test_func)), 0); + ASSERT_NE(test_func(1, 2, 3, 4, VerifyUnreadableElfBacktrace, reinterpret_cast<void*>(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<uintptr_t>(test_func), &frame_num)) { - - VerifyUnreadableElfFrame(backtrace.get(), reinterpret_cast<uintptr_t>(test_func), frame_num); + if (FindFuncFrameInBacktrace(backtrace.get(), reinterpret_cast<uint64_t>(test_func), + &frame_num)) { + VerifyUnreadableElfFrame(backtrace.get(), reinterpret_cast<uint64_t>(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<uintptr_t>(&test_level_one) + 1; - size_t offset; + uint64_t cur_func_offset = reinterpret_cast<uint64_t>(&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(Backtrace::Create(pid, pid)); // Verify that trying to get a function name before doing an unwind works. - uintptr_t cur_func_offset = reinterpret_cast<uintptr_t>(&test_level_one) + 1; - size_t offset; + uint64_t cur_func_offset = reinterpret_cast<uint64_t>(&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<uintptr_t>(device_map); + uint64_t device_map_uint = reinterpret_cast<uint64_t>(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<uintptr_t>(&test_level_one) + 1; + uint64_t cur_func_offset = reinterpret_cast<uint64_t>(&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<uintptr_t>(&ucontext), &ucontext); + SetUcontextSp(reinterpret_cast<uint64_t>(&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<uintptr_t>(&ucontext), frame->sp); + ASSERT_EQ(reinterpret_cast<uint64_t>(&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<BacktraceMap> map(map_create_func(pid, false)); std::unique_ptr<Backtrace> backtrace(create_func(pid, pid, map.get())); - size_t bytes_read = backtrace->Read(reinterpret_cast<uintptr_t>(const_cast<int*>(&value)), + size_t bytes_read = backtrace->Read(reinterpret_cast<uint64_t>(const_cast<int*>(&value)), reinterpret_cast<uint8_t*>(&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 f34fb2d5f..1b8ad19e3 100644 --- a/libbacktrace/include/backtrace/Backtrace.h +++ b/libbacktrace/include/backtrace/Backtrace.h @@ -26,11 +26,11 @@ #include <backtrace/backtrace_constants.h> #include <backtrace/BacktraceMap.h> -#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,14 +77,15 @@ 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. uint64_t dex_pc; // If non-zero, the Dex PC for the ART interpreter. 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__) @@ -139,20 +140,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. @@ -189,9 +190,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<uintptr_t>(-1)) { + if (map->load_bias == static_cast<uint64_t>(-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<unwindstack::Memory> 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 |