Merge "Use the new AndroidUnwinder object." am: f26a9504db
Original change: https://android-review.googlesource.com/c/platform/system/core/+/2029024 Change-Id: If90098d093664581831222bd0644f1412299bded Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
commit
816f2dac18
|
@ -51,12 +51,9 @@
|
|||
#define ATRACE_TAG ATRACE_TAG_BIONIC
|
||||
#include <utils/Trace.h>
|
||||
|
||||
#include <unwindstack/DexFiles.h>
|
||||
#include <unwindstack/JitDebug.h>
|
||||
#include <unwindstack/Maps.h>
|
||||
#include <unwindstack/Memory.h>
|
||||
#include <unwindstack/AndroidUnwinder.h>
|
||||
#include <unwindstack/Error.h>
|
||||
#include <unwindstack/Regs.h>
|
||||
#include <unwindstack/Unwinder.h>
|
||||
|
||||
#include "libdebuggerd/backtrace.h"
|
||||
#include "libdebuggerd/tombstone.h"
|
||||
|
@ -623,9 +620,12 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
|
||||
// TODO: Use seccomp to lock ourselves down.
|
||||
unwindstack::UnwinderFromPid unwinder(256, vm_pid, unwindstack::Regs::CurrentArch());
|
||||
if (!unwinder.Init()) {
|
||||
LOG(FATAL) << "Failed to init unwinder object.";
|
||||
|
||||
unwindstack::AndroidRemoteUnwinder unwinder(vm_pid, unwindstack::Regs::CurrentArch());
|
||||
unwindstack::ErrorData error_data;
|
||||
if (!unwinder.Initialize(error_data)) {
|
||||
LOG(FATAL) << "Failed to initialize unwinder object: "
|
||||
<< unwindstack::GetErrorCodeString(error_data.code);
|
||||
}
|
||||
|
||||
std::string amfd_data;
|
||||
|
|
|
@ -31,12 +31,9 @@
|
|||
#include <android-base/unique_fd.h>
|
||||
#include <async_safe/log.h>
|
||||
#include <bionic/reserved_signals.h>
|
||||
#include <unwindstack/DexFiles.h>
|
||||
#include <unwindstack/JitDebug.h>
|
||||
#include <unwindstack/Maps.h>
|
||||
#include <unwindstack/AndroidUnwinder.h>
|
||||
#include <unwindstack/Memory.h>
|
||||
#include <unwindstack/Regs.h>
|
||||
#include <unwindstack/Unwinder.h>
|
||||
|
||||
#include "debuggerd/handler.h"
|
||||
#include "handler/fallback.h"
|
||||
|
@ -75,11 +72,11 @@ static void debuggerd_fallback_trace(int output_fd, ucontext_t* ucontext) {
|
|||
|
||||
// Do not use the thread cache here because it will call pthread_key_create
|
||||
// which doesn't work in linker code. See b/189803009.
|
||||
// Use a normal cached object because the process is stopped, and there
|
||||
// Use a normal cached object because the thread is stopped, and there
|
||||
// is no chance of data changing between reads.
|
||||
auto process_memory = unwindstack::Memory::CreateProcessMemoryCached(getpid());
|
||||
// TODO: Create this once and store it in a global?
|
||||
unwindstack::UnwinderFromPid unwinder(kMaxFrames, getpid(), process_memory);
|
||||
unwindstack::AndroidLocalUnwinder unwinder(process_memory);
|
||||
dump_backtrace_thread(output_fd, &unwinder, thread);
|
||||
}
|
||||
__linker_disable_fallback_allocator();
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include <android-base/strings.h>
|
||||
#include <android-base/unique_fd.h>
|
||||
#include <log/log.h>
|
||||
#include <unwindstack/AndroidUnwinder.h>
|
||||
#include <unwindstack/Unwinder.h>
|
||||
|
||||
#include "libdebuggerd/types.h"
|
||||
|
@ -57,7 +58,7 @@ static void dump_process_footer(log_t* log, pid_t pid) {
|
|||
_LOG(log, logtype::BACKTRACE, "\n----- end %d -----\n", pid);
|
||||
}
|
||||
|
||||
void dump_backtrace_thread(int output_fd, unwindstack::Unwinder* unwinder,
|
||||
void dump_backtrace_thread(int output_fd, unwindstack::AndroidUnwinder* unwinder,
|
||||
const ThreadInfo& thread) {
|
||||
log_t log;
|
||||
log.tfd = output_fd;
|
||||
|
@ -65,21 +66,17 @@ void dump_backtrace_thread(int output_fd, unwindstack::Unwinder* unwinder,
|
|||
|
||||
_LOG(&log, logtype::BACKTRACE, "\n\"%s\" sysTid=%d\n", thread.thread_name.c_str(), thread.tid);
|
||||
|
||||
unwinder->SetRegs(thread.registers.get());
|
||||
unwinder->Unwind();
|
||||
if (unwinder->NumFrames() == 0) {
|
||||
_LOG(&log, logtype::THREAD, "Unwind failed: tid = %d\n", thread.tid);
|
||||
if (unwinder->LastErrorCode() != unwindstack::ERROR_NONE) {
|
||||
_LOG(&log, logtype::THREAD, " Error code: %s\n", unwinder->LastErrorCodeString());
|
||||
_LOG(&log, logtype::THREAD, " Error address: 0x%" PRIx64 "\n", unwinder->LastErrorAddress());
|
||||
}
|
||||
unwindstack::AndroidUnwinderData data;
|
||||
if (!unwinder->Unwind(thread.registers.get(), data)) {
|
||||
_LOG(&log, logtype::THREAD, "Unwind failed: tid = %d: Error %s\n", thread.tid,
|
||||
data.GetErrorString().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
log_backtrace(&log, unwinder, " ");
|
||||
log_backtrace(&log, unwinder, data, " ");
|
||||
}
|
||||
|
||||
void dump_backtrace(android::base::unique_fd output_fd, unwindstack::Unwinder* unwinder,
|
||||
void dump_backtrace(android::base::unique_fd output_fd, unwindstack::AndroidUnwinder* unwinder,
|
||||
const std::map<pid_t, ThreadInfo>& thread_info, pid_t target_thread) {
|
||||
log_t log;
|
||||
log.tfd = output_fd.get();
|
||||
|
|
|
@ -21,9 +21,8 @@
|
|||
#include "gwp_asan/common.h"
|
||||
#include "gwp_asan/crash_handler.h"
|
||||
|
||||
#include <unwindstack/Maps.h>
|
||||
#include <unwindstack/AndroidUnwinder.h>
|
||||
#include <unwindstack/Memory.h>
|
||||
#include <unwindstack/Regs.h>
|
||||
#include <unwindstack/Unwinder.h>
|
||||
|
||||
#include "tombstone.pb.h"
|
||||
|
@ -106,7 +105,8 @@ bool GwpAsanCrashData::CrashIsMine() const {
|
|||
|
||||
constexpr size_t kMaxTraceLength = gwp_asan::AllocationMetadata::kMaxTraceLengthToCollect;
|
||||
|
||||
void GwpAsanCrashData::AddCauseProtos(Tombstone* tombstone, unwindstack::Unwinder* unwinder) const {
|
||||
void GwpAsanCrashData::AddCauseProtos(Tombstone* tombstone,
|
||||
unwindstack::AndroidUnwinder* unwinder) const {
|
||||
if (!CrashIsMine()) {
|
||||
ALOGE("Internal Error: AddCauseProtos() on a non-GWP-ASan crash.");
|
||||
return;
|
||||
|
@ -140,7 +140,6 @@ void GwpAsanCrashData::AddCauseProtos(Tombstone* tombstone, unwindstack::Unwinde
|
|||
|
||||
heap_object->set_address(__gwp_asan_get_allocation_address(responsible_allocation_));
|
||||
heap_object->set_size(__gwp_asan_get_allocation_size(responsible_allocation_));
|
||||
unwinder->SetDisplayBuildID(true);
|
||||
|
||||
std::unique_ptr<uintptr_t[]> frames(new uintptr_t[kMaxTraceLength]);
|
||||
|
||||
|
|
|
@ -30,16 +30,16 @@
|
|||
|
||||
// Forward delcaration
|
||||
namespace unwindstack {
|
||||
class Unwinder;
|
||||
class AndroidUnwinder;
|
||||
}
|
||||
|
||||
// Dumps a backtrace using a format similar to what Dalvik uses so that the result
|
||||
// can be intermixed in a bug report.
|
||||
void dump_backtrace(android::base::unique_fd output_fd, unwindstack::Unwinder* unwinder,
|
||||
void dump_backtrace(android::base::unique_fd output_fd, unwindstack::AndroidUnwinder* unwinder,
|
||||
const std::map<pid_t, ThreadInfo>& thread_info, pid_t target_thread);
|
||||
|
||||
void dump_backtrace_header(int output_fd);
|
||||
void dump_backtrace_thread(int output_fd, unwindstack::Unwinder* unwinder,
|
||||
void dump_backtrace_thread(int output_fd, unwindstack::AndroidUnwinder* unwinder,
|
||||
const ThreadInfo& thread);
|
||||
void dump_backtrace_footer(int output_fd);
|
||||
|
||||
|
|
|
@ -26,9 +26,15 @@
|
|||
#include "types.h"
|
||||
#include "utility.h"
|
||||
|
||||
// Forward delcarations
|
||||
class Cause;
|
||||
class Tombstone;
|
||||
|
||||
namespace unwindstack {
|
||||
class AndroidUnwinder;
|
||||
class Memory;
|
||||
} // namespace unwindstack
|
||||
|
||||
class GwpAsanCrashData {
|
||||
public:
|
||||
GwpAsanCrashData() = delete;
|
||||
|
@ -52,7 +58,7 @@ class GwpAsanCrashData {
|
|||
// allocator crash state.
|
||||
uintptr_t GetFaultAddress() const;
|
||||
|
||||
void AddCauseProtos(Tombstone* tombstone, unwindstack::Unwinder* unwinder) const;
|
||||
void AddCauseProtos(Tombstone* tombstone, unwindstack::AndroidUnwinder* unwinder) const;
|
||||
|
||||
protected:
|
||||
// Is GWP-ASan responsible for this crash.
|
||||
|
|
|
@ -23,9 +23,15 @@
|
|||
|
||||
#include "scudo/interface.h"
|
||||
|
||||
// Forward delcarations
|
||||
class Cause;
|
||||
class Tombstone;
|
||||
|
||||
namespace unwindstack {
|
||||
class AndroidUnwinder;
|
||||
class Memory;
|
||||
} // namespace unwindstack
|
||||
|
||||
class ScudoCrashData {
|
||||
public:
|
||||
ScudoCrashData() = delete;
|
||||
|
@ -34,12 +40,12 @@ class ScudoCrashData {
|
|||
|
||||
bool CrashIsMine() const;
|
||||
|
||||
void AddCauseProtos(Tombstone* tombstone, unwindstack::Unwinder* unwinder) const;
|
||||
void AddCauseProtos(Tombstone* tombstone, unwindstack::AndroidUnwinder* unwinder) const;
|
||||
|
||||
private:
|
||||
scudo_error_info error_info_ = {};
|
||||
uintptr_t untagged_fault_addr_;
|
||||
|
||||
void FillInCause(Cause* cause, const scudo_error_report* report,
|
||||
unwindstack::Unwinder* unwinder) const;
|
||||
unwindstack::AndroidUnwinder* unwinder) const;
|
||||
};
|
||||
|
|
|
@ -37,7 +37,7 @@ class Tombstone;
|
|||
|
||||
namespace unwindstack {
|
||||
struct FrameData;
|
||||
class Unwinder;
|
||||
class AndroidUnwinder;
|
||||
}
|
||||
|
||||
// The maximum number of frames to save when unwinding.
|
||||
|
@ -51,7 +51,7 @@ int open_tombstone(std::string* path);
|
|||
|
||||
/* Creates a tombstone file and writes the crash dump to it. */
|
||||
void engrave_tombstone(android::base::unique_fd output_fd, android::base::unique_fd proto_fd,
|
||||
unwindstack::Unwinder* unwinder,
|
||||
unwindstack::AndroidUnwinder* unwinder,
|
||||
const std::map<pid_t, ThreadInfo>& thread_info, pid_t target_thread,
|
||||
const ProcessInfo& process_info, OpenFilesList* open_files,
|
||||
std::string* amfd_data);
|
||||
|
@ -59,7 +59,7 @@ void engrave_tombstone(android::base::unique_fd output_fd, android::base::unique
|
|||
void engrave_tombstone_ucontext(int tombstone_fd, int proto_fd, uint64_t abort_msg_address,
|
||||
siginfo_t* siginfo, ucontext_t* ucontext);
|
||||
|
||||
void engrave_tombstone_proto(Tombstone* tombstone, unwindstack::Unwinder* unwinder,
|
||||
void engrave_tombstone_proto(Tombstone* tombstone, unwindstack::AndroidUnwinder* unwinder,
|
||||
const std::map<pid_t, ThreadInfo>& threads, pid_t target_thread,
|
||||
const ProcessInfo& process_info, const OpenFilesList* open_files);
|
||||
|
||||
|
|
|
@ -73,11 +73,13 @@ void _LOG(log_t* log, logtype ltype, const char* fmt, ...) __attribute__((format
|
|||
void _VLOG(log_t* log, logtype ltype, const char* fmt, va_list ap);
|
||||
|
||||
namespace unwindstack {
|
||||
class Unwinder;
|
||||
class AndroidUnwinder;
|
||||
class Memory;
|
||||
struct AndroidUnwinderData;
|
||||
}
|
||||
|
||||
void log_backtrace(log_t* log, unwindstack::Unwinder* unwinder, const char* prefix);
|
||||
void log_backtrace(log_t* log, unwindstack::AndroidUnwinder* unwinder,
|
||||
unwindstack::AndroidUnwinderData& data, const char* prefix);
|
||||
|
||||
ssize_t dump_memory(void* out, size_t len, uint8_t* tags, size_t tags_len, uint64_t* addr,
|
||||
unwindstack::Memory* memory);
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
#include "libdebuggerd/scudo.h"
|
||||
#include "libdebuggerd/tombstone.h"
|
||||
|
||||
#include "unwindstack/AndroidUnwinder.h"
|
||||
#include "unwindstack/Memory.h"
|
||||
#include "unwindstack/Unwinder.h"
|
||||
|
||||
#include <android-base/macros.h>
|
||||
#include <bionic/macros.h>
|
||||
|
@ -80,7 +80,7 @@ bool ScudoCrashData::CrashIsMine() const {
|
|||
}
|
||||
|
||||
void ScudoCrashData::FillInCause(Cause* cause, const scudo_error_report* report,
|
||||
unwindstack::Unwinder* unwinder) const {
|
||||
unwindstack::AndroidUnwinder* unwinder) const {
|
||||
MemoryError* memory_error = cause->mutable_memory_error();
|
||||
HeapObject* heap_object = memory_error->mutable_heap();
|
||||
|
||||
|
@ -102,7 +102,6 @@ void ScudoCrashData::FillInCause(Cause* cause, const scudo_error_report* report,
|
|||
|
||||
heap_object->set_address(report->allocation_address);
|
||||
heap_object->set_size(report->allocation_size);
|
||||
unwinder->SetDisplayBuildID(true);
|
||||
|
||||
heap_object->set_allocation_tid(report->allocation_tid);
|
||||
for (size_t i = 0; i < arraysize(report->allocation_trace) && report->allocation_trace[i]; ++i) {
|
||||
|
@ -123,7 +122,8 @@ void ScudoCrashData::FillInCause(Cause* cause, const scudo_error_report* report,
|
|||
set_human_readable_cause(cause, untagged_fault_addr_);
|
||||
}
|
||||
|
||||
void ScudoCrashData::AddCauseProtos(Tombstone* tombstone, unwindstack::Unwinder* unwinder) const {
|
||||
void ScudoCrashData::AddCauseProtos(Tombstone* tombstone,
|
||||
unwindstack::AndroidUnwinder* unwinder) const {
|
||||
size_t report_num = 0;
|
||||
while (report_num < sizeof(error_info_.reports) / sizeof(error_info_.reports[0]) &&
|
||||
error_info_.reports[report_num].error_type != UNKNOWN) {
|
||||
|
|
|
@ -36,9 +36,9 @@
|
|||
#include <async_safe/log.h>
|
||||
#include <log/log.h>
|
||||
#include <private/android_filesystem_config.h>
|
||||
#include <unwindstack/Memory.h>
|
||||
#include <unwindstack/AndroidUnwinder.h>
|
||||
#include <unwindstack/Error.h>
|
||||
#include <unwindstack/Regs.h>
|
||||
#include <unwindstack/Unwinder.h>
|
||||
|
||||
#include "libdebuggerd/backtrace.h"
|
||||
#include "libdebuggerd/open_files_list.h"
|
||||
|
@ -101,12 +101,16 @@ void engrave_tombstone_ucontext(int tombstone_fd, int proto_fd, uint64_t abort_m
|
|||
}
|
||||
}
|
||||
|
||||
auto process_memory =
|
||||
unwindstack::Memory::CreateProcessMemoryCached(getpid());
|
||||
unwindstack::UnwinderFromPid unwinder(kMaxFrames, pid, unwindstack::Regs::CurrentArch(), nullptr,
|
||||
process_memory);
|
||||
if (!unwinder.Init()) {
|
||||
async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG, "failed to init unwinder object");
|
||||
// Do not use the thread cache here because it will call pthread_key_create
|
||||
// which doesn't work in linker code. See b/189803009.
|
||||
// Use a normal cached object because the thread is stopped, and there
|
||||
// is no chance of data changing between reads.
|
||||
auto process_memory = unwindstack::Memory::CreateProcessMemoryCached(getpid());
|
||||
unwindstack::AndroidLocalUnwinder unwinder(process_memory);
|
||||
unwindstack::ErrorData error;
|
||||
if (!unwinder.Initialize(error)) {
|
||||
async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG, "failed to init unwinder object: %s",
|
||||
unwindstack::GetErrorCodeString(error.code));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -116,7 +120,8 @@ void engrave_tombstone_ucontext(int tombstone_fd, int proto_fd, uint64_t abort_m
|
|||
process_info, nullptr, nullptr);
|
||||
}
|
||||
|
||||
void engrave_tombstone(unique_fd output_fd, unique_fd proto_fd, unwindstack::Unwinder* unwinder,
|
||||
void engrave_tombstone(unique_fd output_fd, unique_fd proto_fd,
|
||||
unwindstack::AndroidUnwinder* unwinder,
|
||||
const std::map<pid_t, ThreadInfo>& threads, pid_t target_thread,
|
||||
const ProcessInfo& process_info, OpenFilesList* open_files,
|
||||
std::string* amfd_data) {
|
||||
|
|
|
@ -56,10 +56,11 @@
|
|||
#include <private/android_filesystem_config.h>
|
||||
|
||||
#include <procinfo/process.h>
|
||||
#include <unwindstack/AndroidUnwinder.h>
|
||||
#include <unwindstack/Error.h>
|
||||
#include <unwindstack/MapInfo.h>
|
||||
#include <unwindstack/Maps.h>
|
||||
#include <unwindstack/Memory.h>
|
||||
#include <unwindstack/Regs.h>
|
||||
#include <unwindstack/Unwinder.h>
|
||||
|
||||
#include "libdebuggerd/open_files_list.h"
|
||||
#include "libdebuggerd/utility.h"
|
||||
|
@ -189,7 +190,7 @@ void set_human_readable_cause(Cause* cause, uint64_t fault_addr) {
|
|||
error_type_str, diff, byte_suffix, location_str, heap_object.size(), heap_object.address()));
|
||||
}
|
||||
|
||||
static void dump_probable_cause(Tombstone* tombstone, unwindstack::Unwinder* unwinder,
|
||||
static void dump_probable_cause(Tombstone* tombstone, unwindstack::AndroidUnwinder* unwinder,
|
||||
const ProcessInfo& process_info, const ThreadInfo& main_thread) {
|
||||
#if defined(USE_SCUDO)
|
||||
ScudoCrashData scudo_crash_data(unwinder->GetProcessMemory().get(), process_info);
|
||||
|
@ -245,9 +246,9 @@ static void dump_probable_cause(Tombstone* tombstone, unwindstack::Unwinder* unw
|
|||
}
|
||||
}
|
||||
|
||||
static void dump_abort_message(Tombstone* tombstone, unwindstack::Unwinder* unwinder,
|
||||
static void dump_abort_message(Tombstone* tombstone,
|
||||
std::shared_ptr<unwindstack::Memory>& process_memory,
|
||||
const ProcessInfo& process_info) {
|
||||
std::shared_ptr<unwindstack::Memory> process_memory = unwinder->GetProcessMemory();
|
||||
uintptr_t address = process_info.abort_msg_address;
|
||||
if (address == 0) {
|
||||
return;
|
||||
|
@ -348,7 +349,7 @@ void fill_in_backtrace_frame(BacktraceFrame* f, const unwindstack::FrameData& fr
|
|||
f->set_build_id(frame.map_info->GetPrintableBuildID());
|
||||
}
|
||||
|
||||
static void dump_registers(unwindstack::Unwinder* unwinder,
|
||||
static void dump_registers(unwindstack::AndroidUnwinder* unwinder,
|
||||
const std::unique_ptr<unwindstack::Regs>& regs, Thread& thread,
|
||||
bool memory_dump) {
|
||||
if (regs == nullptr) {
|
||||
|
@ -402,27 +403,9 @@ static void dump_registers(unwindstack::Unwinder* unwinder,
|
|||
});
|
||||
}
|
||||
|
||||
static void log_unwinder_error(unwindstack::Unwinder* unwinder) {
|
||||
if (unwinder->LastErrorCode() == unwindstack::ERROR_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG, " error code: %s",
|
||||
unwinder->LastErrorCodeString());
|
||||
async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG, " error address: 0x%" PRIx64,
|
||||
unwinder->LastErrorAddress());
|
||||
}
|
||||
|
||||
static void dump_thread_backtrace(unwindstack::Unwinder* unwinder, Thread& thread) {
|
||||
if (unwinder->NumFrames() == 0) {
|
||||
async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG, "failed to unwind");
|
||||
log_unwinder_error(unwinder);
|
||||
return;
|
||||
}
|
||||
|
||||
unwinder->SetDisplayBuildID(true);
|
||||
static void dump_thread_backtrace(std::vector<unwindstack::FrameData>& frames, Thread& thread) {
|
||||
std::set<std::string> unreadable_elf_files;
|
||||
for (const auto& frame : unwinder->frames()) {
|
||||
for (const auto& frame : frames) {
|
||||
BacktraceFrame* f = thread.add_current_backtrace();
|
||||
fill_in_backtrace_frame(f, frame);
|
||||
if (frame.map_info != nullptr && frame.map_info->ElfFileNotReadable()) {
|
||||
|
@ -446,7 +429,7 @@ static void dump_thread_backtrace(unwindstack::Unwinder* unwinder, Thread& threa
|
|||
}
|
||||
}
|
||||
|
||||
static void dump_thread(Tombstone* tombstone, unwindstack::Unwinder* unwinder,
|
||||
static void dump_thread(Tombstone* tombstone, unwindstack::AndroidUnwinder* unwinder,
|
||||
const ThreadInfo& thread_info, bool memory_dump = false) {
|
||||
Thread thread;
|
||||
|
||||
|
@ -455,36 +438,29 @@ static void dump_thread(Tombstone* tombstone, unwindstack::Unwinder* unwinder,
|
|||
thread.set_tagged_addr_ctrl(thread_info.tagged_addr_ctrl);
|
||||
thread.set_pac_enabled_keys(thread_info.pac_enabled_keys);
|
||||
|
||||
if (thread_info.pid == getpid() && thread_info.pid != thread_info.tid) {
|
||||
// Fallback path for non-main thread, doing unwind from running process.
|
||||
unwindstack::ThreadUnwinder thread_unwinder(kMaxFrames, unwinder->GetMaps());
|
||||
if (!thread_unwinder.Init()) {
|
||||
async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG,
|
||||
"Unable to initialize ThreadUnwinder object.");
|
||||
log_unwinder_error(&thread_unwinder);
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_ptr<unwindstack::Regs> initial_regs;
|
||||
thread_unwinder.UnwindWithSignal(BIONIC_SIGNAL_BACKTRACE, thread_info.tid, &initial_regs);
|
||||
dump_registers(&thread_unwinder, initial_regs, thread, memory_dump);
|
||||
dump_thread_backtrace(&thread_unwinder, thread);
|
||||
unwindstack::AndroidUnwinderData data;
|
||||
// Indicate we want a copy of the initial registers.
|
||||
data.saved_initial_regs = std::make_optional<std::unique_ptr<unwindstack::Regs>>();
|
||||
bool unwind_ret;
|
||||
if (thread_info.registers != nullptr) {
|
||||
unwind_ret = unwinder->Unwind(thread_info.registers.get(), data);
|
||||
} else {
|
||||
dump_registers(unwinder, thread_info.registers, thread, memory_dump);
|
||||
std::unique_ptr<unwindstack::Regs> regs_copy(thread_info.registers->Clone());
|
||||
unwinder->SetRegs(regs_copy.get());
|
||||
unwinder->Unwind();
|
||||
dump_thread_backtrace(unwinder, thread);
|
||||
unwind_ret = unwinder->Unwind(thread_info.tid, data);
|
||||
}
|
||||
if (!unwind_ret) {
|
||||
async_safe_format_log(ANDROID_LOG_ERROR, LOG_TAG, "Unwind failed for tid %d: Error %s",
|
||||
thread_info.tid, data.GetErrorString().c_str());
|
||||
} else {
|
||||
dump_thread_backtrace(data.frames, thread);
|
||||
}
|
||||
dump_registers(unwinder, *data.saved_initial_regs, thread, memory_dump);
|
||||
|
||||
auto& threads = *tombstone->mutable_threads();
|
||||
threads[thread_info.tid] = thread;
|
||||
}
|
||||
|
||||
static void dump_mappings(Tombstone* tombstone, unwindstack::Unwinder* unwinder) {
|
||||
unwindstack::Maps* maps = unwinder->GetMaps();
|
||||
std::shared_ptr<unwindstack::Memory> process_memory = unwinder->GetProcessMemory();
|
||||
|
||||
static void dump_mappings(Tombstone* tombstone, unwindstack::Maps* maps,
|
||||
std::shared_ptr<unwindstack::Memory>& process_memory) {
|
||||
for (const auto& map_info : *maps) {
|
||||
auto* map = tombstone->add_memory_mappings();
|
||||
map->set_begin_address(map_info->start());
|
||||
|
@ -593,7 +569,8 @@ static void dump_logcat(Tombstone* tombstone, pid_t pid) {
|
|||
}
|
||||
|
||||
static void dump_tags_around_fault_addr(Signal* signal, const Tombstone& tombstone,
|
||||
unwindstack::Unwinder* unwinder, uintptr_t fault_addr) {
|
||||
std::shared_ptr<unwindstack::Memory>& process_memory,
|
||||
uintptr_t fault_addr) {
|
||||
if (tombstone.arch() != Architecture::ARM64) return;
|
||||
|
||||
fault_addr = untag_address(fault_addr);
|
||||
|
@ -604,8 +581,6 @@ static void dump_tags_around_fault_addr(Signal* signal, const Tombstone& tombsto
|
|||
// a valid address for us to dump tags from.
|
||||
if (fault_addr < kBytesToRead / 2) return;
|
||||
|
||||
unwindstack::Memory* memory = unwinder->GetProcessMemory().get();
|
||||
|
||||
constexpr uintptr_t kRowStartMask = ~(kNumTagColumns * kTagGranuleSize - 1);
|
||||
size_t start_address = (fault_addr & kRowStartMask) - kBytesToRead / 2;
|
||||
MemoryDump tag_dump;
|
||||
|
@ -614,7 +589,7 @@ static void dump_tags_around_fault_addr(Signal* signal, const Tombstone& tombsto
|
|||
// Attempt to read the first tag. If reading fails, this likely indicates the
|
||||
// lowest touched page is inaccessible or not marked with PROT_MTE.
|
||||
// Fast-forward over pages until one has tags, or we exhaust the search range.
|
||||
while (memory->ReadTag(start_address) < 0) {
|
||||
while (process_memory->ReadTag(start_address) < 0) {
|
||||
size_t page_size = sysconf(_SC_PAGE_SIZE);
|
||||
size_t bytes_to_next_page = page_size - (start_address % page_size);
|
||||
if (bytes_to_next_page >= granules_to_read * kTagGranuleSize) return;
|
||||
|
@ -626,7 +601,7 @@ static void dump_tags_around_fault_addr(Signal* signal, const Tombstone& tombsto
|
|||
std::string* mte_tags = tag_dump.mutable_arm_mte_metadata()->mutable_memory_tags();
|
||||
|
||||
for (size_t i = 0; i < granules_to_read; ++i) {
|
||||
long tag = memory->ReadTag(start_address + i * kTagGranuleSize);
|
||||
long tag = process_memory->ReadTag(start_address + i * kTagGranuleSize);
|
||||
if (tag < 0) break;
|
||||
mte_tags->push_back(static_cast<uint8_t>(tag));
|
||||
}
|
||||
|
@ -636,7 +611,7 @@ static void dump_tags_around_fault_addr(Signal* signal, const Tombstone& tombsto
|
|||
}
|
||||
}
|
||||
|
||||
void engrave_tombstone_proto(Tombstone* tombstone, unwindstack::Unwinder* unwinder,
|
||||
void engrave_tombstone_proto(Tombstone* tombstone, unwindstack::AndroidUnwinder* unwinder,
|
||||
const std::map<pid_t, ThreadInfo>& threads, pid_t target_thread,
|
||||
const ProcessInfo& process_info, const OpenFilesList* open_files) {
|
||||
Tombstone result;
|
||||
|
@ -691,12 +666,12 @@ void engrave_tombstone_proto(Tombstone* tombstone, unwindstack::Unwinder* unwind
|
|||
sig.set_has_fault_address(true);
|
||||
uintptr_t fault_addr = process_info.maybe_tagged_fault_address;
|
||||
sig.set_fault_address(fault_addr);
|
||||
dump_tags_around_fault_addr(&sig, result, unwinder, fault_addr);
|
||||
dump_tags_around_fault_addr(&sig, result, unwinder->GetProcessMemory(), fault_addr);
|
||||
}
|
||||
|
||||
*result.mutable_signal_info() = sig;
|
||||
|
||||
dump_abort_message(&result, unwinder, process_info);
|
||||
dump_abort_message(&result, unwinder->GetProcessMemory(), process_info);
|
||||
|
||||
// Dump the main thread, but save the memory around the registers.
|
||||
dump_thread(&result, unwinder, main_thread, /* memory_dump */ true);
|
||||
|
@ -709,7 +684,7 @@ void engrave_tombstone_proto(Tombstone* tombstone, unwindstack::Unwinder* unwind
|
|||
|
||||
dump_probable_cause(&result, unwinder, process_info, main_thread);
|
||||
|
||||
dump_mappings(&result, unwinder);
|
||||
dump_mappings(&result, unwinder->GetMaps(), unwinder->GetProcessMemory());
|
||||
|
||||
// Only dump logs on debuggable devices.
|
||||
if (android::base::GetBoolProperty("ro.debuggable", false)) {
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include <bionic/reserved_signals.h>
|
||||
#include <debuggerd/handler.h>
|
||||
#include <log/log.h>
|
||||
#include <unwindstack/AndroidUnwinder.h>
|
||||
#include <unwindstack/Memory.h>
|
||||
#include <unwindstack/Unwinder.h>
|
||||
|
||||
|
@ -483,10 +484,10 @@ std::string describe_pac_enabled_keys(long value) {
|
|||
return describe_end(value, desc);
|
||||
}
|
||||
|
||||
void log_backtrace(log_t* log, unwindstack::Unwinder* unwinder, const char* prefix) {
|
||||
void log_backtrace(log_t* log, unwindstack::AndroidUnwinder* unwinder,
|
||||
unwindstack::AndroidUnwinderData& data, const char* prefix) {
|
||||
std::set<std::string> unreadable_elf_files;
|
||||
unwinder->SetDisplayBuildID(true);
|
||||
for (const auto& frame : unwinder->frames()) {
|
||||
for (const auto& frame : data.frames) {
|
||||
if (frame.map_info != nullptr && frame.map_info->ElfFileNotReadable()) {
|
||||
unreadable_elf_files.emplace(frame.map_info->name());
|
||||
}
|
||||
|
@ -509,7 +510,7 @@ void log_backtrace(log_t* log, unwindstack::Unwinder* unwinder, const char* pref
|
|||
}
|
||||
}
|
||||
|
||||
for (const auto& frame : unwinder->frames()) {
|
||||
for (const auto& frame : data.frames) {
|
||||
_LOG(log, logtype::BACKTRACE, "%s%s\n", prefix, unwinder->FormatFrame(frame).c_str());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue