Loading debuggerd/Android.bp +0 −1 Original line number Diff line number Diff line Loading @@ -282,7 +282,6 @@ cc_test { "libdebuggerd/test/elf_fake.cpp", "libdebuggerd/test/log_fake.cpp", "libdebuggerd/test/open_files_list_test.cpp", "libdebuggerd/test/tombstone_test.cpp", "libdebuggerd/test/utility_test.cpp", ], Loading debuggerd/libdebuggerd/gwp_asan.cpp +0 −109 Original line number Diff line number Diff line Loading @@ -161,112 +161,3 @@ void GwpAsanCrashData::AddCauseProtos(Tombstone* tombstone, unwindstack::Unwinde set_human_readable_cause(cause, crash_address_); } void GwpAsanCrashData::DumpCause(log_t* log) const { if (!CrashIsMine()) { ALOGE("Internal Error: DumpCause() on a non-GWP-ASan crash."); return; } if (error_ == gwp_asan::Error::UNKNOWN) { _LOG(log, logtype::HEADER, "Cause: [GWP-ASan]: Unknown error occurred at 0x%" PRIxPTR ".\n", crash_address_); return; } if (!responsible_allocation_) { _LOG(log, logtype::HEADER, "Cause: [GWP-ASan]: %s at 0x%" PRIxPTR ".\n", error_string_, crash_address_); return; } uintptr_t alloc_address = __gwp_asan_get_allocation_address(responsible_allocation_); size_t alloc_size = __gwp_asan_get_allocation_size(responsible_allocation_); uintptr_t diff; const char* location_str; if (crash_address_ < alloc_address) { // Buffer Underflow, 6 bytes left of a 41-byte allocation at 0xdeadbeef. location_str = "left of"; diff = alloc_address - crash_address_; } else if (crash_address_ - alloc_address < alloc_size) { // Use After Free, 40 bytes into a 41-byte allocation at 0xdeadbeef. location_str = "into"; diff = crash_address_ - alloc_address; } else { // Buffer Overflow, 6 bytes right of a 41-byte allocation at 0xdeadbeef, or // Invalid Free, 47 bytes right of a 41-byte allocation at 0xdeadbeef. location_str = "right of"; diff = crash_address_ - alloc_address; if (error_ == gwp_asan::Error::BUFFER_OVERFLOW) { diff -= alloc_size; } } // Suffix of 'bytes', i.e. 4 bytes' vs. '1 byte'. const char* byte_suffix = "s"; if (diff == 1) { byte_suffix = ""; } _LOG(log, logtype::HEADER, "Cause: [GWP-ASan]: %s, %" PRIuPTR " byte%s %s a %zu-byte allocation at 0x%" PRIxPTR "\n", error_string_, diff, byte_suffix, location_str, alloc_size, alloc_address); } bool GwpAsanCrashData::HasDeallocationTrace() const { assert(CrashIsMine() && "HasDeallocationTrace(): Crash is not mine!"); if (!responsible_allocation_ || !__gwp_asan_is_deallocated(responsible_allocation_)) { return false; } return true; } void GwpAsanCrashData::DumpDeallocationTrace(log_t* log, unwindstack::Unwinder* unwinder) const { assert(HasDeallocationTrace() && "DumpDeallocationTrace(): No dealloc trace!"); uint64_t thread_id = __gwp_asan_get_deallocation_thread_id(responsible_allocation_); std::unique_ptr<uintptr_t[]> frames(new uintptr_t[kMaxTraceLength]); size_t num_frames = __gwp_asan_get_deallocation_trace(responsible_allocation_, frames.get(), kMaxTraceLength); if (thread_id == gwp_asan::kInvalidThreadID) { _LOG(log, logtype::BACKTRACE, "\ndeallocated by thread <unknown>:\n"); } else { _LOG(log, logtype::BACKTRACE, "\ndeallocated by thread %" PRIu64 ":\n", thread_id); } unwinder->SetDisplayBuildID(true); for (size_t i = 0; i < num_frames; ++i) { unwindstack::FrameData frame_data = unwinder->BuildFrameFromPcOnly(frames[i]); frame_data.num = i; _LOG(log, logtype::BACKTRACE, " %s\n", unwinder->FormatFrame(frame_data).c_str()); } } bool GwpAsanCrashData::HasAllocationTrace() const { assert(CrashIsMine() && "HasAllocationTrace(): Crash is not mine!"); return responsible_allocation_ != nullptr; } void GwpAsanCrashData::DumpAllocationTrace(log_t* log, unwindstack::Unwinder* unwinder) const { assert(HasAllocationTrace() && "DumpAllocationTrace(): No dealloc trace!"); uint64_t thread_id = __gwp_asan_get_allocation_thread_id(responsible_allocation_); std::unique_ptr<uintptr_t[]> frames(new uintptr_t[kMaxTraceLength]); size_t num_frames = __gwp_asan_get_allocation_trace(responsible_allocation_, frames.get(), kMaxTraceLength); if (thread_id == gwp_asan::kInvalidThreadID) { _LOG(log, logtype::BACKTRACE, "\nallocated by thread <unknown>:\n"); } else { _LOG(log, logtype::BACKTRACE, "\nallocated by thread %" PRIu64 ":\n", thread_id); } unwinder->SetDisplayBuildID(true); for (size_t i = 0; i < num_frames; ++i) { unwindstack::FrameData frame_data = unwinder->BuildFrameFromPcOnly(frames[i]); frame_data.num = i; _LOG(log, logtype::BACKTRACE, " %s\n", unwinder->FormatFrame(frame_data).c_str()); } } debuggerd/libdebuggerd/include/libdebuggerd/gwp_asan.h +0 −20 Original line number Diff line number Diff line Loading @@ -52,26 +52,6 @@ class GwpAsanCrashData { // allocator crash state. uintptr_t GetFaultAddress() const; // Dump the GWP-ASan stringified cause of this crash. May only be called if // CrashIsMine() returns true. void DumpCause(log_t* log) const; // Returns whether this crash has a deallocation trace. May only be called if // CrashIsMine() returns true. bool HasDeallocationTrace() const; // Dump the GWP-ASan deallocation trace for this crash. May only be called if // HasDeallocationTrace() returns true. void DumpDeallocationTrace(log_t* log, unwindstack::Unwinder* unwinder) const; // Returns whether this crash has a allocation trace. May only be called if // CrashIsMine() returns true. bool HasAllocationTrace() const; // Dump the GWP-ASan allocation trace for this crash. May only be called if // HasAllocationTrace() returns true. void DumpAllocationTrace(log_t* log, unwindstack::Unwinder* unwinder) const; void AddCauseProtos(Tombstone* tombstone, unwindstack::Unwinder* unwinder) const; protected: Loading debuggerd/libdebuggerd/include/libdebuggerd/scudo.h +0 −4 Original line number Diff line number Diff line Loading @@ -34,16 +34,12 @@ class ScudoCrashData { bool CrashIsMine() const; void DumpCause(log_t* log, unwindstack::Unwinder* unwinder) const; void AddCauseProtos(Tombstone* tombstone, unwindstack::Unwinder* unwinder) const; private: scudo_error_info error_info_ = {}; uintptr_t untagged_fault_addr_; void DumpReport(const scudo_error_report* report, log_t* log, unwindstack::Unwinder* unwinder) const; void FillInCause(Cause* cause, const scudo_error_report* report, unwindstack::Unwinder* unwinder) const; }; debuggerd/libdebuggerd/scudo.cpp +0 −84 Original line number Diff line number Diff line Loading @@ -130,87 +130,3 @@ void ScudoCrashData::AddCauseProtos(Tombstone* tombstone, unwindstack::Unwinder* FillInCause(tombstone->add_causes(), &error_info_.reports[report_num++], unwinder); } } void ScudoCrashData::DumpCause(log_t* log, unwindstack::Unwinder* unwinder) const { if (error_info_.reports[1].error_type != UNKNOWN) { _LOG(log, logtype::HEADER, "\nNote: multiple potential causes for this crash were detected, listing them in " "decreasing order of likelihood.\n"); } 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) { DumpReport(&error_info_.reports[report_num++], log, unwinder); } } void ScudoCrashData::DumpReport(const scudo_error_report* report, log_t* log, unwindstack::Unwinder* unwinder) const { const char *error_type_str; switch (report->error_type) { case USE_AFTER_FREE: error_type_str = "Use After Free"; break; case BUFFER_OVERFLOW: error_type_str = "Buffer Overflow"; break; case BUFFER_UNDERFLOW: error_type_str = "Buffer Underflow"; break; default: error_type_str = "Unknown"; break; } uintptr_t diff; const char* location_str; if (untagged_fault_addr_ < report->allocation_address) { // Buffer Underflow, 6 bytes left of a 41-byte allocation at 0xdeadbeef. location_str = "left of"; diff = report->allocation_address - untagged_fault_addr_; } else if (untagged_fault_addr_ - report->allocation_address < report->allocation_size) { // Use After Free, 40 bytes into a 41-byte allocation at 0xdeadbeef. location_str = "into"; diff = untagged_fault_addr_ - report->allocation_address; } else { // Buffer Overflow, 6 bytes right of a 41-byte allocation at 0xdeadbeef. location_str = "right of"; diff = untagged_fault_addr_ - report->allocation_address - report->allocation_size; } // Suffix of 'bytes', i.e. 4 bytes' vs. '1 byte'. const char* byte_suffix = "s"; if (diff == 1) { byte_suffix = ""; } _LOG(log, logtype::HEADER, "\nCause: [MTE]: %s, %" PRIuPTR " byte%s %s a %zu-byte allocation at 0x%" PRIxPTR "\n", error_type_str, diff, byte_suffix, location_str, report->allocation_size, report->allocation_address); if (report->allocation_trace[0]) { _LOG(log, logtype::BACKTRACE, "\nallocated by thread %u:\n", report->allocation_tid); unwinder->SetDisplayBuildID(true); for (size_t i = 0; i < arraysize(report->allocation_trace) && report->allocation_trace[i]; ++i) { unwindstack::FrameData frame_data = unwinder->BuildFrameFromPcOnly(report->allocation_trace[i]); frame_data.num = i; _LOG(log, logtype::BACKTRACE, " %s\n", unwinder->FormatFrame(frame_data).c_str()); } } if (report->deallocation_trace[0]) { _LOG(log, logtype::BACKTRACE, "\ndeallocated by thread %u:\n", report->deallocation_tid); unwinder->SetDisplayBuildID(true); for (size_t i = 0; i < arraysize(report->deallocation_trace) && report->deallocation_trace[i]; ++i) { unwindstack::FrameData frame_data = unwinder->BuildFrameFromPcOnly(report->deallocation_trace[i]); frame_data.num = i; _LOG(log, logtype::BACKTRACE, " %s\n", unwinder->FormatFrame(frame_data).c_str()); } } } Loading
debuggerd/Android.bp +0 −1 Original line number Diff line number Diff line Loading @@ -282,7 +282,6 @@ cc_test { "libdebuggerd/test/elf_fake.cpp", "libdebuggerd/test/log_fake.cpp", "libdebuggerd/test/open_files_list_test.cpp", "libdebuggerd/test/tombstone_test.cpp", "libdebuggerd/test/utility_test.cpp", ], Loading
debuggerd/libdebuggerd/gwp_asan.cpp +0 −109 Original line number Diff line number Diff line Loading @@ -161,112 +161,3 @@ void GwpAsanCrashData::AddCauseProtos(Tombstone* tombstone, unwindstack::Unwinde set_human_readable_cause(cause, crash_address_); } void GwpAsanCrashData::DumpCause(log_t* log) const { if (!CrashIsMine()) { ALOGE("Internal Error: DumpCause() on a non-GWP-ASan crash."); return; } if (error_ == gwp_asan::Error::UNKNOWN) { _LOG(log, logtype::HEADER, "Cause: [GWP-ASan]: Unknown error occurred at 0x%" PRIxPTR ".\n", crash_address_); return; } if (!responsible_allocation_) { _LOG(log, logtype::HEADER, "Cause: [GWP-ASan]: %s at 0x%" PRIxPTR ".\n", error_string_, crash_address_); return; } uintptr_t alloc_address = __gwp_asan_get_allocation_address(responsible_allocation_); size_t alloc_size = __gwp_asan_get_allocation_size(responsible_allocation_); uintptr_t diff; const char* location_str; if (crash_address_ < alloc_address) { // Buffer Underflow, 6 bytes left of a 41-byte allocation at 0xdeadbeef. location_str = "left of"; diff = alloc_address - crash_address_; } else if (crash_address_ - alloc_address < alloc_size) { // Use After Free, 40 bytes into a 41-byte allocation at 0xdeadbeef. location_str = "into"; diff = crash_address_ - alloc_address; } else { // Buffer Overflow, 6 bytes right of a 41-byte allocation at 0xdeadbeef, or // Invalid Free, 47 bytes right of a 41-byte allocation at 0xdeadbeef. location_str = "right of"; diff = crash_address_ - alloc_address; if (error_ == gwp_asan::Error::BUFFER_OVERFLOW) { diff -= alloc_size; } } // Suffix of 'bytes', i.e. 4 bytes' vs. '1 byte'. const char* byte_suffix = "s"; if (diff == 1) { byte_suffix = ""; } _LOG(log, logtype::HEADER, "Cause: [GWP-ASan]: %s, %" PRIuPTR " byte%s %s a %zu-byte allocation at 0x%" PRIxPTR "\n", error_string_, diff, byte_suffix, location_str, alloc_size, alloc_address); } bool GwpAsanCrashData::HasDeallocationTrace() const { assert(CrashIsMine() && "HasDeallocationTrace(): Crash is not mine!"); if (!responsible_allocation_ || !__gwp_asan_is_deallocated(responsible_allocation_)) { return false; } return true; } void GwpAsanCrashData::DumpDeallocationTrace(log_t* log, unwindstack::Unwinder* unwinder) const { assert(HasDeallocationTrace() && "DumpDeallocationTrace(): No dealloc trace!"); uint64_t thread_id = __gwp_asan_get_deallocation_thread_id(responsible_allocation_); std::unique_ptr<uintptr_t[]> frames(new uintptr_t[kMaxTraceLength]); size_t num_frames = __gwp_asan_get_deallocation_trace(responsible_allocation_, frames.get(), kMaxTraceLength); if (thread_id == gwp_asan::kInvalidThreadID) { _LOG(log, logtype::BACKTRACE, "\ndeallocated by thread <unknown>:\n"); } else { _LOG(log, logtype::BACKTRACE, "\ndeallocated by thread %" PRIu64 ":\n", thread_id); } unwinder->SetDisplayBuildID(true); for (size_t i = 0; i < num_frames; ++i) { unwindstack::FrameData frame_data = unwinder->BuildFrameFromPcOnly(frames[i]); frame_data.num = i; _LOG(log, logtype::BACKTRACE, " %s\n", unwinder->FormatFrame(frame_data).c_str()); } } bool GwpAsanCrashData::HasAllocationTrace() const { assert(CrashIsMine() && "HasAllocationTrace(): Crash is not mine!"); return responsible_allocation_ != nullptr; } void GwpAsanCrashData::DumpAllocationTrace(log_t* log, unwindstack::Unwinder* unwinder) const { assert(HasAllocationTrace() && "DumpAllocationTrace(): No dealloc trace!"); uint64_t thread_id = __gwp_asan_get_allocation_thread_id(responsible_allocation_); std::unique_ptr<uintptr_t[]> frames(new uintptr_t[kMaxTraceLength]); size_t num_frames = __gwp_asan_get_allocation_trace(responsible_allocation_, frames.get(), kMaxTraceLength); if (thread_id == gwp_asan::kInvalidThreadID) { _LOG(log, logtype::BACKTRACE, "\nallocated by thread <unknown>:\n"); } else { _LOG(log, logtype::BACKTRACE, "\nallocated by thread %" PRIu64 ":\n", thread_id); } unwinder->SetDisplayBuildID(true); for (size_t i = 0; i < num_frames; ++i) { unwindstack::FrameData frame_data = unwinder->BuildFrameFromPcOnly(frames[i]); frame_data.num = i; _LOG(log, logtype::BACKTRACE, " %s\n", unwinder->FormatFrame(frame_data).c_str()); } }
debuggerd/libdebuggerd/include/libdebuggerd/gwp_asan.h +0 −20 Original line number Diff line number Diff line Loading @@ -52,26 +52,6 @@ class GwpAsanCrashData { // allocator crash state. uintptr_t GetFaultAddress() const; // Dump the GWP-ASan stringified cause of this crash. May only be called if // CrashIsMine() returns true. void DumpCause(log_t* log) const; // Returns whether this crash has a deallocation trace. May only be called if // CrashIsMine() returns true. bool HasDeallocationTrace() const; // Dump the GWP-ASan deallocation trace for this crash. May only be called if // HasDeallocationTrace() returns true. void DumpDeallocationTrace(log_t* log, unwindstack::Unwinder* unwinder) const; // Returns whether this crash has a allocation trace. May only be called if // CrashIsMine() returns true. bool HasAllocationTrace() const; // Dump the GWP-ASan allocation trace for this crash. May only be called if // HasAllocationTrace() returns true. void DumpAllocationTrace(log_t* log, unwindstack::Unwinder* unwinder) const; void AddCauseProtos(Tombstone* tombstone, unwindstack::Unwinder* unwinder) const; protected: Loading
debuggerd/libdebuggerd/include/libdebuggerd/scudo.h +0 −4 Original line number Diff line number Diff line Loading @@ -34,16 +34,12 @@ class ScudoCrashData { bool CrashIsMine() const; void DumpCause(log_t* log, unwindstack::Unwinder* unwinder) const; void AddCauseProtos(Tombstone* tombstone, unwindstack::Unwinder* unwinder) const; private: scudo_error_info error_info_ = {}; uintptr_t untagged_fault_addr_; void DumpReport(const scudo_error_report* report, log_t* log, unwindstack::Unwinder* unwinder) const; void FillInCause(Cause* cause, const scudo_error_report* report, unwindstack::Unwinder* unwinder) const; };
debuggerd/libdebuggerd/scudo.cpp +0 −84 Original line number Diff line number Diff line Loading @@ -130,87 +130,3 @@ void ScudoCrashData::AddCauseProtos(Tombstone* tombstone, unwindstack::Unwinder* FillInCause(tombstone->add_causes(), &error_info_.reports[report_num++], unwinder); } } void ScudoCrashData::DumpCause(log_t* log, unwindstack::Unwinder* unwinder) const { if (error_info_.reports[1].error_type != UNKNOWN) { _LOG(log, logtype::HEADER, "\nNote: multiple potential causes for this crash were detected, listing them in " "decreasing order of likelihood.\n"); } 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) { DumpReport(&error_info_.reports[report_num++], log, unwinder); } } void ScudoCrashData::DumpReport(const scudo_error_report* report, log_t* log, unwindstack::Unwinder* unwinder) const { const char *error_type_str; switch (report->error_type) { case USE_AFTER_FREE: error_type_str = "Use After Free"; break; case BUFFER_OVERFLOW: error_type_str = "Buffer Overflow"; break; case BUFFER_UNDERFLOW: error_type_str = "Buffer Underflow"; break; default: error_type_str = "Unknown"; break; } uintptr_t diff; const char* location_str; if (untagged_fault_addr_ < report->allocation_address) { // Buffer Underflow, 6 bytes left of a 41-byte allocation at 0xdeadbeef. location_str = "left of"; diff = report->allocation_address - untagged_fault_addr_; } else if (untagged_fault_addr_ - report->allocation_address < report->allocation_size) { // Use After Free, 40 bytes into a 41-byte allocation at 0xdeadbeef. location_str = "into"; diff = untagged_fault_addr_ - report->allocation_address; } else { // Buffer Overflow, 6 bytes right of a 41-byte allocation at 0xdeadbeef. location_str = "right of"; diff = untagged_fault_addr_ - report->allocation_address - report->allocation_size; } // Suffix of 'bytes', i.e. 4 bytes' vs. '1 byte'. const char* byte_suffix = "s"; if (diff == 1) { byte_suffix = ""; } _LOG(log, logtype::HEADER, "\nCause: [MTE]: %s, %" PRIuPTR " byte%s %s a %zu-byte allocation at 0x%" PRIxPTR "\n", error_type_str, diff, byte_suffix, location_str, report->allocation_size, report->allocation_address); if (report->allocation_trace[0]) { _LOG(log, logtype::BACKTRACE, "\nallocated by thread %u:\n", report->allocation_tid); unwinder->SetDisplayBuildID(true); for (size_t i = 0; i < arraysize(report->allocation_trace) && report->allocation_trace[i]; ++i) { unwindstack::FrameData frame_data = unwinder->BuildFrameFromPcOnly(report->allocation_trace[i]); frame_data.num = i; _LOG(log, logtype::BACKTRACE, " %s\n", unwinder->FormatFrame(frame_data).c_str()); } } if (report->deallocation_trace[0]) { _LOG(log, logtype::BACKTRACE, "\ndeallocated by thread %u:\n", report->deallocation_tid); unwinder->SetDisplayBuildID(true); for (size_t i = 0; i < arraysize(report->deallocation_trace) && report->deallocation_trace[i]; ++i) { unwindstack::FrameData frame_data = unwinder->BuildFrameFromPcOnly(report->deallocation_trace[i]); frame_data.num = i; _LOG(log, logtype::BACKTRACE, " %s\n", unwinder->FormatFrame(frame_data).c_str()); } } }