diff --git a/debuggerd/crash_dump.cpp b/debuggerd/crash_dump.cpp index 3e998802b..6a381453e 100644 --- a/debuggerd/crash_dump.cpp +++ b/debuggerd/crash_dump.cpp @@ -254,9 +254,7 @@ static void ParseArgs(int argc, char** argv, pid_t* pseudothread_tid, DebuggerdD } static void ReadCrashInfo(unique_fd& fd, siginfo_t* siginfo, - std::unique_ptr* regs, uintptr_t* abort_msg_address, - uintptr_t* fdsan_table_address, uintptr_t* gwp_asan_state, - uintptr_t* gwp_asan_metadata) { + std::unique_ptr* regs, ProcessInfo* process_info) { std::aligned_storage::type buf; CrashInfo* crash_info = reinterpret_cast(&buf); ssize_t rc = TEMP_FAILURE_RETRY(read(fd.get(), &buf, sizeof(buf))); @@ -288,19 +286,16 @@ static void ReadCrashInfo(unique_fd& fd, siginfo_t* siginfo, } } - *fdsan_table_address = 0; - *gwp_asan_state = 0; - *gwp_asan_metadata = 0; switch (crash_info->header.version) { case 3: - *gwp_asan_state = crash_info->data.v3.gwp_asan_state; - *gwp_asan_metadata = crash_info->data.v3.gwp_asan_metadata; + process_info->gwp_asan_state = crash_info->data.v3.gwp_asan_state; + process_info->gwp_asan_metadata = crash_info->data.v3.gwp_asan_metadata; FALLTHROUGH_INTENDED; case 2: - *fdsan_table_address = crash_info->data.v2.fdsan_table_address; + process_info->fdsan_table_address = crash_info->data.v2.fdsan_table_address; FALLTHROUGH_INTENDED; case 1: - *abort_msg_address = crash_info->data.v1.abort_msg_address; + process_info->abort_msg_address = crash_info->data.v1.abort_msg_address; *siginfo = crash_info->data.v1.siginfo; regs->reset(unwindstack::Regs::CreateFromUcontext(unwindstack::Regs::CurrentArch(), &crash_info->data.v1.ucontext)); @@ -425,10 +420,7 @@ int main(int argc, char** argv) { ATRACE_NAME("after reparent"); pid_t pseudothread_tid; DebuggerdDumpType dump_type; - uintptr_t abort_msg_address = 0; - uintptr_t fdsan_table_address = 0; - uintptr_t gwp_asan_state = 0; - uintptr_t gwp_asan_metadata = 0; + ProcessInfo process_info; Initialize(argv); ParseArgs(argc, argv, &pseudothread_tid, &dump_type); @@ -489,8 +481,7 @@ int main(int argc, char** argv) { if (thread == g_target_thread) { // Read the thread's registers along with the rest of the crash info out of the pipe. - ReadCrashInfo(input_pipe, &siginfo, &info.registers, &abort_msg_address, - &fdsan_table_address, &gwp_asan_state, &gwp_asan_metadata); + ReadCrashInfo(input_pipe, &siginfo, &info.registers, &process_info); info.siginfo = &siginfo; info.signo = info.siginfo->si_signo; } else { @@ -599,14 +590,14 @@ int main(int argc, char** argv) { } else { { ATRACE_NAME("fdsan table dump"); - populate_fdsan_table(&open_files, unwinder.GetProcessMemory(), fdsan_table_address); + populate_fdsan_table(&open_files, unwinder.GetProcessMemory(), + process_info.fdsan_table_address); } { ATRACE_NAME("engrave_tombstone"); - engrave_tombstone(std::move(g_output_fd), &unwinder, thread_info, g_target_thread, - abort_msg_address, &open_files, &amfd_data, gwp_asan_state, - gwp_asan_metadata); + engrave_tombstone(std::move(g_output_fd), &unwinder, thread_info, g_target_thread, process_info, + &open_files, &amfd_data); } } diff --git a/debuggerd/libdebuggerd/gwp_asan.cpp b/debuggerd/libdebuggerd/gwp_asan.cpp index 53df783dc..fe3a1730d 100644 --- a/debuggerd/libdebuggerd/gwp_asan.cpp +++ b/debuggerd/libdebuggerd/gwp_asan.cpp @@ -63,12 +63,11 @@ static const gwp_asan::AllocationMetadata* retrieve_gwp_asan_metadata( } GwpAsanCrashData::GwpAsanCrashData(unwindstack::Memory* process_memory, - uintptr_t gwp_asan_state_ptr, uintptr_t gwp_asan_metadata_ptr, - const ThreadInfo& thread_info) { - if (!process_memory || !gwp_asan_metadata_ptr || !gwp_asan_state_ptr) return; + const ProcessInfo& process_info, const ThreadInfo& thread_info) { + if (!process_memory || !process_info.gwp_asan_metadata || !process_info.gwp_asan_state) return; // Extract the GWP-ASan regions from the dead process. - if (!retrieve_gwp_asan_state(process_memory, gwp_asan_state_ptr, &state_)) return; - metadata_.reset(retrieve_gwp_asan_metadata(process_memory, state_, gwp_asan_metadata_ptr)); + if (!retrieve_gwp_asan_state(process_memory, process_info.gwp_asan_state, &state_)) return; + metadata_.reset(retrieve_gwp_asan_metadata(process_memory, state_, process_info.gwp_asan_metadata)); if (!metadata_.get()) return; // Get the external crash address from the thread info. diff --git a/debuggerd/libdebuggerd/include/libdebuggerd/gwp_asan.h b/debuggerd/libdebuggerd/include/libdebuggerd/gwp_asan.h index aef4c62aa..6c8873341 100644 --- a/debuggerd/libdebuggerd/include/libdebuggerd/gwp_asan.h +++ b/debuggerd/libdebuggerd/include/libdebuggerd/gwp_asan.h @@ -38,8 +38,8 @@ class GwpAsanCrashData { // still be responsible, as it terminates when it detects an internal error // (double free, invalid free). In these cases, we will retrieve the fault // address from the GWP-ASan allocator's state. - GwpAsanCrashData(unwindstack::Memory* process_memory, uintptr_t gwp_asan_state_ptr, - uintptr_t gwp_asan_metadata_ptr, const ThreadInfo& thread_info); + GwpAsanCrashData(unwindstack::Memory* process_memory, const ProcessInfo& process_info, + const ThreadInfo& thread_info); // Is GWP-ASan responsible for this crash. bool CrashIsMine() const; diff --git a/debuggerd/libdebuggerd/include/libdebuggerd/tombstone.h b/debuggerd/libdebuggerd/include/libdebuggerd/tombstone.h index 291d994b3..3ff7d629d 100644 --- a/debuggerd/libdebuggerd/include/libdebuggerd/tombstone.h +++ b/debuggerd/libdebuggerd/include/libdebuggerd/tombstone.h @@ -44,18 +44,13 @@ constexpr size_t kMaxFrames = 256; int open_tombstone(std::string* path); /* Creates a tombstone file and writes the crash dump to it. */ -void engrave_tombstone(int tombstone_fd, unwindstack::Unwinder* unwinder, - const OpenFilesList* open_files, pid_t pid, pid_t tid, - const std::string& process_name, const std::map& threads, - uint64_t abort_msg_address, std::string* amfd_data); +void engrave_tombstone(android::base::unique_fd output_fd, unwindstack::Unwinder* unwinder, + const std::map& thread_info, pid_t target_thread, + const ProcessInfo& process_info, OpenFilesList* open_files, + std::string* amfd_data); void engrave_tombstone_ucontext(int tombstone_fd, uint64_t abort_msg_address, siginfo_t* siginfo, ucontext_t* ucontext); -void engrave_tombstone(android::base::unique_fd output_fd, unwindstack::Unwinder* unwinder, - const std::map& thread_info, pid_t target_thread, - uint64_t abort_msg_address, OpenFilesList* open_files, - std::string* amfd_data, uintptr_t gwp_asan_state, - uintptr_t gwp_asan_metadata); #endif // _DEBUGGERD_TOMBSTONE_H diff --git a/debuggerd/libdebuggerd/include/libdebuggerd/types.h b/debuggerd/libdebuggerd/include/libdebuggerd/types.h index eb4b1b844..4f681c260 100644 --- a/debuggerd/libdebuggerd/include/libdebuggerd/types.h +++ b/debuggerd/libdebuggerd/include/libdebuggerd/types.h @@ -35,3 +35,10 @@ struct ThreadInfo { int signo = 0; siginfo_t* siginfo = nullptr; }; + +struct ProcessInfo { + uintptr_t abort_msg_address = 0; + uintptr_t fdsan_table_address = 0; + uintptr_t gwp_asan_state = 0; + uintptr_t gwp_asan_metadata = 0; +}; diff --git a/debuggerd/libdebuggerd/test/tombstone_test.cpp b/debuggerd/libdebuggerd/test/tombstone_test.cpp index eed95bc39..aec8c6030 100644 --- a/debuggerd/libdebuggerd/test/tombstone_test.cpp +++ b/debuggerd/libdebuggerd/test/tombstone_test.cpp @@ -371,7 +371,7 @@ public: GwpAsanCrashDataTest( gwp_asan::Error error, const gwp_asan::AllocationMetadata *responsible_allocation) : - GwpAsanCrashData(nullptr, 0u, 0u, ThreadInfo{}) { + GwpAsanCrashData(nullptr, ProcessInfo{}, ThreadInfo{}) { is_gwp_asan_responsible_ = true; error_ = error; responsible_allocation_ = responsible_allocation; diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp index fd52e8113..b3f059c1c 100644 --- a/debuggerd/libdebuggerd/tombstone.cpp +++ b/debuggerd/libdebuggerd/tombstone.cpp @@ -376,8 +376,7 @@ void dump_memory_and_code(log_t* log, unwindstack::Maps* maps, unwindstack::Memo } static bool dump_thread(log_t* log, unwindstack::Unwinder* unwinder, const ThreadInfo& thread_info, - uint64_t abort_msg_address, bool primary_thread, - const GwpAsanCrashData& gwp_asan_crash_data) { + const ProcessInfo& process_info, bool primary_thread) { log->current_tid = thread_info.tid; if (!primary_thread) { _LOG(log, logtype::THREAD, "--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---\n"); @@ -388,15 +387,21 @@ static bool dump_thread(log_t* log, unwindstack::Unwinder* unwinder, const Threa dump_signal_info(log, thread_info, unwinder->GetProcessMemory().get()); } - if (primary_thread && gwp_asan_crash_data.CrashIsMine()) { - gwp_asan_crash_data.DumpCause(log); + std::unique_ptr gwp_asan_crash_data; + if (primary_thread) { + gwp_asan_crash_data = std::make_unique(unwinder->GetProcessMemory().get(), + process_info, thread_info); + } + + if (primary_thread && gwp_asan_crash_data->CrashIsMine()) { + gwp_asan_crash_data->DumpCause(log); } else if (thread_info.siginfo) { dump_probable_cause(log, thread_info.siginfo, unwinder->GetMaps(), thread_info.registers.get()); } if (primary_thread) { - dump_abort_message(log, unwinder->GetProcessMemory().get(), abort_msg_address); + dump_abort_message(log, unwinder->GetProcessMemory().get(), process_info.abort_msg_address); } dump_registers(log, thread_info.registers.get()); @@ -413,12 +418,12 @@ static bool dump_thread(log_t* log, unwindstack::Unwinder* unwinder, const Threa } if (primary_thread) { - if (gwp_asan_crash_data.HasDeallocationTrace()) { - gwp_asan_crash_data.DumpDeallocationTrace(log, unwinder); + if (gwp_asan_crash_data->HasDeallocationTrace()) { + gwp_asan_crash_data->DumpDeallocationTrace(log, unwinder); } - if (gwp_asan_crash_data.HasAllocationTrace()) { - gwp_asan_crash_data.DumpAllocationTrace(log, unwinder); + if (gwp_asan_crash_data->HasAllocationTrace()) { + gwp_asan_crash_data->DumpAllocationTrace(log, unwinder); } unwindstack::Maps* maps = unwinder->GetMaps(); @@ -601,15 +606,16 @@ void engrave_tombstone_ucontext(int tombstone_fd, uint64_t abort_msg_address, si LOG(FATAL) << "Failed to init unwinder object."; } - engrave_tombstone(unique_fd(dup(tombstone_fd)), &unwinder, threads, tid, abort_msg_address, - nullptr, nullptr, 0u, 0u); + ProcessInfo process_info; + process_info.abort_msg_address = abort_msg_address; + engrave_tombstone(unique_fd(dup(tombstone_fd)), &unwinder, threads, tid, process_info, nullptr, + nullptr); } void engrave_tombstone(unique_fd output_fd, unwindstack::Unwinder* unwinder, const std::map& threads, pid_t target_thread, - uint64_t abort_msg_address, OpenFilesList* open_files, - std::string* amfd_data, uintptr_t gwp_asan_state_ptr, - uintptr_t gwp_asan_metadata_ptr) { + const ProcessInfo& process_info, OpenFilesList* open_files, + std::string* amfd_data) { // don't copy log messages to tombstone unless this is a dev device bool want_logs = android::base::GetBoolProperty("ro.debuggable", false); @@ -628,12 +634,7 @@ void engrave_tombstone(unique_fd output_fd, unwindstack::Unwinder* unwinder, LOG(FATAL) << "failed to find target thread"; } - GwpAsanCrashData gwp_asan_crash_data(unwinder->GetProcessMemory().get(), - gwp_asan_state_ptr, - gwp_asan_metadata_ptr, it->second); - - dump_thread(&log, unwinder, it->second, abort_msg_address, true, - gwp_asan_crash_data); + dump_thread(&log, unwinder, it->second, process_info, true); if (want_logs) { dump_logs(&log, it->second.pid, 50); @@ -644,7 +645,7 @@ void engrave_tombstone(unique_fd output_fd, unwindstack::Unwinder* unwinder, continue; } - dump_thread(&log, unwinder, thread_info, 0, false, gwp_asan_crash_data); + dump_thread(&log, unwinder, thread_info, process_info, false); } if (open_files) {