Change all uintptr_t to uint64_t in API.
In order to support the offline unwinding properly, get rid of the
usage of non-fixed type uintptr_t from all API calls.
In addition, completely remove the old local and remote unwinding code
that used libunwind.
The next step will be to move the offline unwinding to the new unwinder.
Bug: 65682279
Test: Ran unit tests for libbacktrace/debuggerd.
Test: Ran debuggerd -b on a few arm and arm64 processes.
Test: Ran crasher and crasher64 and verified tombstones look correct.
Change-Id: Ib0c6cee3ad6785a102b74908a3d8e5e93e5c6b33
diff --git a/libbacktrace/Android.bp b/libbacktrace/Android.bp
index 9eaeae8..d9eed76 100644
--- a/libbacktrace/Android.bp
+++ b/libbacktrace/Android.bp
@@ -50,9 +50,6 @@
"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 5bb6edc..1195e5f 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 @@
}
}
-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 @@
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 @@
// 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 @@
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 474d099..d61b281 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 @@
}
}
-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 072ffd2..60a9117 100644
--- a/libbacktrace/BacktraceCurrent.h
+++ b/libbacktrace/BacktraceCurrent.h
@@ -40,9 +40,9 @@
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 0f1ae11..2a657b8 100644
--- a/libbacktrace/BacktraceMap.cpp
+++ b/libbacktrace/BacktraceMap.cpp
@@ -38,7 +38,7 @@
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 30845a2..a056716 100644
--- a/libbacktrace/BacktraceOffline.cpp
+++ b/libbacktrace/BacktraceOffline.cpp
@@ -57,7 +57,7 @@
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 @@
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 @@
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 @@
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 @@
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 fcde379..e028cd8 100644
--- a/libbacktrace/BacktraceOffline.h
+++ b/libbacktrace/BacktraceOffline.h
@@ -57,9 +57,9 @@
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 @@
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 fd8b713..bf6b16f 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 @@
}
#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 @@
#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 d110b48..1ae3adf 100644
--- a/libbacktrace/BacktracePtrace.h
+++ b/libbacktrace/BacktracePtrace.h
@@ -29,9 +29,9 @@
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 3ccf13c..0000000
--- 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 3656104..0000000
--- 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 3cab0d1..798c769 100644
--- a/libbacktrace/UnwindMap.cpp
+++ b/libbacktrace/UnwindMap.cpp
@@ -134,7 +134,7 @@
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 6ffdafd..15544e8 100644
--- a/libbacktrace/UnwindMap.h
+++ b/libbacktrace/UnwindMap.h
@@ -55,7 +55,7 @@
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 2155b8a..0000000
--- 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 4688110..0000000
--- 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 b0345a1..441dc81 100644
--- a/libbacktrace/UnwindStack.cpp
+++ b/libbacktrace/UnwindStack.cpp
@@ -88,7 +88,7 @@
UnwindStackCurrent::UnwindStackCurrent(pid_t pid, pid_t tid, BacktraceMap* map)
: BacktraceCurrent(pid, tid, map) {}
-std::string UnwindStackCurrent::GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) {
+std::string UnwindStackCurrent::GetFunctionNameRaw(uint64_t pc, uint64_t* offset) {
return GetMap()->GetFunctionName(pc, offset);
}
@@ -111,7 +111,7 @@
UnwindStackPtrace::UnwindStackPtrace(pid_t pid, pid_t tid, BacktraceMap* map)
: BacktracePtrace(pid, tid, map), memory_(pid) {}
-std::string UnwindStackPtrace::GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) {
+std::string UnwindStackPtrace::GetFunctionNameRaw(uint64_t pc, uint64_t* offset) {
return GetMap()->GetFunctionName(pc, offset);
}
@@ -127,6 +127,6 @@
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 ee2a706..498ad4e 100644
--- a/libbacktrace/UnwindStack.h
+++ b/libbacktrace/UnwindStack.h
@@ -32,7 +32,7 @@
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 @@
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 93406dc..60c7952 100644
--- a/libbacktrace/UnwindStackMap.cpp
+++ b/libbacktrace/UnwindStackMap.cpp
@@ -57,7 +57,7 @@
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 @@
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 @@
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 12c5909..6b98809 100644
--- a/libbacktrace/UnwindStackMap.h
+++ b/libbacktrace/UnwindStackMap.h
@@ -33,9 +33,9 @@
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 e92bc61..e2a7441 100644
--- a/libbacktrace/backtrace_offline_test.cpp
+++ b/libbacktrace/backtrace_offline_test.cpp
@@ -75,20 +75,20 @@
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 @@
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 @@
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 @@
// 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 @@
// 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 @@
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 @@
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 @@
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 @@
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 57b7553..10152f7 100644
--- a/libbacktrace/backtrace_test.cpp
+++ b/libbacktrace/backtrace_test.cpp
@@ -745,8 +745,8 @@
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 @@
}
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
// 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 @@
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_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 @@
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 @@
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 @@
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 @@
#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 @@
#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 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 @@
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 @@
// 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 @@
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 @@
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 5922664..18e9f61 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,13 +77,14 @@
struct backtrace_frame_data_t {
size_t num; // The current fame number.
- uintptr_t pc; // The absolute pc.
- uintptr_t rel_pc; // The relative pc.
- uintptr_t sp; // The top of the stack.
+ uint64_t pc; // The absolute pc.
+ uint64_t rel_pc; // The relative pc.
+ uint64_t sp; // The top of the stack.
size_t stack_size; // The size of the stack, zero indicate an unknown stack size.
backtrace_map_t map; // The map associated with the given pc.
std::string func_name; // The function name associated with this pc, NULL if not found.
- uintptr_t func_offset; // pc relative to the start of the function, only valid if func_name is not NULL.
+ uint64_t func_offset; // pc relative to the start of the function, only valid if func_name is not
+ // NULL.
};
#if defined(__APPLE__)
@@ -138,20 +139,20 @@
// Get the function name and offset into the function given the pc.
// If the string is empty, then no valid function name was found,
// or the pc is not in any valid map.
- virtual std::string GetFunctionName(uintptr_t pc, uintptr_t* offset,
+ virtual std::string GetFunctionName(uint64_t pc, uint64_t* offset,
const backtrace_map_t* map = NULL);
// Fill in the map data associated with the given pc.
- virtual void FillInMap(uintptr_t pc, backtrace_map_t* map);
+ virtual void FillInMap(uint64_t pc, backtrace_map_t* map);
// Read the data at a specific address.
- virtual bool ReadWord(uintptr_t ptr, word_t* out_value) = 0;
+ virtual bool ReadWord(uint64_t ptr, word_t* out_value) = 0;
// Read arbitrary data from a specific address. If a read request would
// span from one map to another, this call only reads up until the end
// of the current map.
// Returns the total number of bytes actually read.
- virtual size_t Read(uintptr_t addr, uint8_t* buffer, size_t bytes) = 0;
+ virtual size_t Read(uint64_t addr, uint8_t* buffer, size_t bytes) = 0;
// Create a string representing the formatted line of backtrace information
// for a single frame.
@@ -188,9 +189,9 @@
// 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 4ae68dd..4d020e6 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 @@
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 @@
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 @@
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