summaryrefslogtreecommitdiffstats
path: root/libbacktrace
diff options
context:
space:
mode:
authorChristopher Ferris <cferris@google.com>2018-01-19 23:30:33 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2018-01-19 23:30:33 +0000
commite20b4a48fee974901e73039f6add426df857e3de (patch)
tree8818fbffe638b0523535829829e047a6ca0ec82b /libbacktrace
parentb6d7f2655d19f8de30b3957a12715afddf7fc522 (diff)
parent7937a36c8e24ef2dc5105a2a6b67f395934b2e2f (diff)
downloadsystem_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.bp3
-rw-r--r--libbacktrace/Backtrace.cpp12
-rw-r--r--libbacktrace/BacktraceCurrent.cpp4
-rw-r--r--libbacktrace/BacktraceCurrent.h4
-rw-r--r--libbacktrace/BacktraceMap.cpp2
-rw-r--r--libbacktrace/BacktraceOffline.cpp17
-rw-r--r--libbacktrace/BacktraceOffline.h6
-rw-r--r--libbacktrace/BacktracePtrace.cpp6
-rw-r--r--libbacktrace/BacktracePtrace.h4
-rw-r--r--libbacktrace/UnwindCurrent.cpp165
-rw-r--r--libbacktrace/UnwindCurrent.h51
-rw-r--r--libbacktrace/UnwindMap.cpp2
-rw-r--r--libbacktrace/UnwindMap.h2
-rw-r--r--libbacktrace/UnwindPtrace.cpp186
-rw-r--r--libbacktrace/UnwindPtrace.h48
-rw-r--r--libbacktrace/UnwindStack.cpp6
-rw-r--r--libbacktrace/UnwindStack.h6
-rw-r--r--libbacktrace/UnwindStackMap.cpp8
-rw-r--r--libbacktrace/UnwindStackMap.h4
-rw-r--r--libbacktrace/backtrace_offline_test.cpp43
-rw-r--r--libbacktrace/backtrace_test.cpp115
-rw-r--r--libbacktrace/include/backtrace/Backtrace.h27
-rw-r--r--libbacktrace/include/backtrace/BacktraceMap.h22
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