Loading debuggerd/libdebuggerd/gwp_asan.cpp +4 −56 Original line number Original line Diff line number Diff line Loading @@ -157,60 +157,6 @@ void GwpAsanCrashData::DumpCause(log_t* log) const { error_string_, diff, byte_suffix, location_str, alloc_size, alloc_address); error_string_, diff, byte_suffix, location_str, alloc_size, alloc_address); } } // Build a frame for symbolization using the maps from the provided unwinder. // The constructed frame contains just enough information to be used to // symbolize a GWP-ASan stack trace. static unwindstack::FrameData BuildFrame(unwindstack::Unwinder* unwinder, uintptr_t pc, size_t frame_num) { unwindstack::FrameData frame; frame.num = frame_num; unwindstack::Maps* maps = unwinder->GetMaps(); unwindstack::MapInfo* map_info = maps->Find(pc); if (!map_info) { frame.rel_pc = pc; return frame; } unwindstack::ArchEnum arch = unwindstack::Regs::CurrentArch(); unwindstack::Elf* elf = map_info->GetElf(unwinder->GetProcessMemory(), arch); uint64_t relative_pc = elf->GetRelPc(pc, map_info); uint64_t pc_adjustment = unwindstack::GetPcAdjustment(relative_pc, elf, arch); relative_pc -= pc_adjustment; // The debug PC may be different if the PC comes from the JIT. uint64_t debug_pc = relative_pc; // If we don't have a valid ELF file, check the JIT. if (!elf->valid()) { unwindstack::JitDebug jit_debug(unwinder->GetProcessMemory()); uint64_t jit_pc = pc - pc_adjustment; unwindstack::Elf* jit_elf = jit_debug.GetElf(maps, jit_pc); if (jit_elf != nullptr) { debug_pc = jit_pc; elf = jit_elf; } } // Copy all the things we need into the frame for symbolization. frame.rel_pc = relative_pc; frame.pc = pc - pc_adjustment; frame.map_name = map_info->name; frame.map_elf_start_offset = map_info->elf_start_offset; frame.map_exact_offset = map_info->offset; frame.map_start = map_info->start; frame.map_end = map_info->end; frame.map_flags = map_info->flags; frame.map_load_bias = elf->GetLoadBias(); if (!elf->GetFunctionName(relative_pc, &frame.function_name, &frame.function_offset)) { frame.function_name = ""; frame.function_offset = 0; } return frame; } constexpr size_t kMaxTraceLength = gwp_asan::AllocationMetadata::kMaxTraceLengthToCollect; constexpr size_t kMaxTraceLength = gwp_asan::AllocationMetadata::kMaxTraceLengthToCollect; bool GwpAsanCrashData::HasDeallocationTrace() const { bool GwpAsanCrashData::HasDeallocationTrace() const { Loading @@ -237,7 +183,8 @@ void GwpAsanCrashData::DumpDeallocationTrace(log_t* log, unwindstack::Unwinder* unwinder->SetDisplayBuildID(true); unwinder->SetDisplayBuildID(true); for (size_t i = 0; i < num_frames; ++i) { for (size_t i = 0; i < num_frames; ++i) { unwindstack::FrameData frame_data = BuildFrame(unwinder, frames.get()[i], i); unwindstack::FrameData frame_data = unwinder->BuildFrameFromPcOnly(frames.get()[i]); frame_data.num = i; _LOG(log, logtype::BACKTRACE, " %s\n", unwinder->FormatFrame(frame_data).c_str()); _LOG(log, logtype::BACKTRACE, " %s\n", unwinder->FormatFrame(frame_data).c_str()); } } } } Loading @@ -263,7 +210,8 @@ void GwpAsanCrashData::DumpAllocationTrace(log_t* log, unwindstack::Unwinder* un unwinder->SetDisplayBuildID(true); unwinder->SetDisplayBuildID(true); for (size_t i = 0; i < num_frames; ++i) { for (size_t i = 0; i < num_frames; ++i) { unwindstack::FrameData frame_data = BuildFrame(unwinder, frames.get()[i], i); unwindstack::FrameData frame_data = unwinder->BuildFrameFromPcOnly(frames.get()[i]); frame_data.num = i; _LOG(log, logtype::BACKTRACE, " %s\n", unwinder->FormatFrame(frame_data).c_str()); _LOG(log, logtype::BACKTRACE, " %s\n", unwinder->FormatFrame(frame_data).c_str()); } } } } libunwindstack/Unwinder.cpp +50 −0 Original line number Original line Diff line number Diff line Loading @@ -395,4 +395,54 @@ bool UnwinderFromPid::Init(ArchEnum arch) { return true; return true; } } FrameData Unwinder::BuildFrameFromPcOnly(uint64_t pc) { FrameData frame; Maps* maps = GetMaps(); MapInfo* map_info = maps->Find(pc); if (!map_info) { frame.rel_pc = pc; return frame; } ArchEnum arch = Regs::CurrentArch(); Elf* elf = map_info->GetElf(GetProcessMemory(), arch); uint64_t relative_pc = elf->GetRelPc(pc, map_info); uint64_t pc_adjustment = GetPcAdjustment(relative_pc, elf, arch); relative_pc -= pc_adjustment; // The debug PC may be different if the PC comes from the JIT. uint64_t debug_pc = relative_pc; // If we don't have a valid ELF file, check the JIT. if (!elf->valid()) { JitDebug jit_debug(GetProcessMemory()); uint64_t jit_pc = pc - pc_adjustment; Elf* jit_elf = jit_debug.GetElf(maps, jit_pc); if (jit_elf != nullptr) { debug_pc = jit_pc; elf = jit_elf; } } // Copy all the things we need into the frame for symbolization. frame.rel_pc = relative_pc; frame.pc = pc - pc_adjustment; frame.map_name = map_info->name; frame.map_elf_start_offset = map_info->elf_start_offset; frame.map_exact_offset = map_info->offset; frame.map_start = map_info->start; frame.map_end = map_info->end; frame.map_flags = map_info->flags; frame.map_load_bias = elf->GetLoadBias(); if (!resolve_names_ || !elf->GetFunctionName(relative_pc, &frame.function_name, &frame.function_offset)) { frame.function_name = ""; frame.function_offset = 0; } return frame; } } // namespace unwindstack } // namespace unwindstack libunwindstack/include/unwindstack/Unwinder.h +7 −0 Original line number Original line Diff line number Diff line Loading @@ -114,6 +114,13 @@ class Unwinder { ErrorCode LastErrorCode() { return last_error_.code; } ErrorCode LastErrorCode() { return last_error_.code; } uint64_t LastErrorAddress() { return last_error_.address; } uint64_t LastErrorAddress() { return last_error_.address; } // Builds a frame for symbolization using the maps from this unwinder. The // constructed frame contains just enough information to be used to symbolize // frames collected by frame-pointer unwinding that's done outside of // libunwindstack. This is used by tombstoned to symbolize frame pointer-based // stack traces that are collected by tools such as GWP-ASan and MTE. FrameData BuildFrameFromPcOnly(uint64_t pc); protected: protected: Unwinder(size_t max_frames) : max_frames_(max_frames) { frames_.reserve(max_frames); } Unwinder(size_t max_frames) : max_frames_(max_frames) { frames_.reserve(max_frames); } Loading Loading
debuggerd/libdebuggerd/gwp_asan.cpp +4 −56 Original line number Original line Diff line number Diff line Loading @@ -157,60 +157,6 @@ void GwpAsanCrashData::DumpCause(log_t* log) const { error_string_, diff, byte_suffix, location_str, alloc_size, alloc_address); error_string_, diff, byte_suffix, location_str, alloc_size, alloc_address); } } // Build a frame for symbolization using the maps from the provided unwinder. // The constructed frame contains just enough information to be used to // symbolize a GWP-ASan stack trace. static unwindstack::FrameData BuildFrame(unwindstack::Unwinder* unwinder, uintptr_t pc, size_t frame_num) { unwindstack::FrameData frame; frame.num = frame_num; unwindstack::Maps* maps = unwinder->GetMaps(); unwindstack::MapInfo* map_info = maps->Find(pc); if (!map_info) { frame.rel_pc = pc; return frame; } unwindstack::ArchEnum arch = unwindstack::Regs::CurrentArch(); unwindstack::Elf* elf = map_info->GetElf(unwinder->GetProcessMemory(), arch); uint64_t relative_pc = elf->GetRelPc(pc, map_info); uint64_t pc_adjustment = unwindstack::GetPcAdjustment(relative_pc, elf, arch); relative_pc -= pc_adjustment; // The debug PC may be different if the PC comes from the JIT. uint64_t debug_pc = relative_pc; // If we don't have a valid ELF file, check the JIT. if (!elf->valid()) { unwindstack::JitDebug jit_debug(unwinder->GetProcessMemory()); uint64_t jit_pc = pc - pc_adjustment; unwindstack::Elf* jit_elf = jit_debug.GetElf(maps, jit_pc); if (jit_elf != nullptr) { debug_pc = jit_pc; elf = jit_elf; } } // Copy all the things we need into the frame for symbolization. frame.rel_pc = relative_pc; frame.pc = pc - pc_adjustment; frame.map_name = map_info->name; frame.map_elf_start_offset = map_info->elf_start_offset; frame.map_exact_offset = map_info->offset; frame.map_start = map_info->start; frame.map_end = map_info->end; frame.map_flags = map_info->flags; frame.map_load_bias = elf->GetLoadBias(); if (!elf->GetFunctionName(relative_pc, &frame.function_name, &frame.function_offset)) { frame.function_name = ""; frame.function_offset = 0; } return frame; } constexpr size_t kMaxTraceLength = gwp_asan::AllocationMetadata::kMaxTraceLengthToCollect; constexpr size_t kMaxTraceLength = gwp_asan::AllocationMetadata::kMaxTraceLengthToCollect; bool GwpAsanCrashData::HasDeallocationTrace() const { bool GwpAsanCrashData::HasDeallocationTrace() const { Loading @@ -237,7 +183,8 @@ void GwpAsanCrashData::DumpDeallocationTrace(log_t* log, unwindstack::Unwinder* unwinder->SetDisplayBuildID(true); unwinder->SetDisplayBuildID(true); for (size_t i = 0; i < num_frames; ++i) { for (size_t i = 0; i < num_frames; ++i) { unwindstack::FrameData frame_data = BuildFrame(unwinder, frames.get()[i], i); unwindstack::FrameData frame_data = unwinder->BuildFrameFromPcOnly(frames.get()[i]); frame_data.num = i; _LOG(log, logtype::BACKTRACE, " %s\n", unwinder->FormatFrame(frame_data).c_str()); _LOG(log, logtype::BACKTRACE, " %s\n", unwinder->FormatFrame(frame_data).c_str()); } } } } Loading @@ -263,7 +210,8 @@ void GwpAsanCrashData::DumpAllocationTrace(log_t* log, unwindstack::Unwinder* un unwinder->SetDisplayBuildID(true); unwinder->SetDisplayBuildID(true); for (size_t i = 0; i < num_frames; ++i) { for (size_t i = 0; i < num_frames; ++i) { unwindstack::FrameData frame_data = BuildFrame(unwinder, frames.get()[i], i); unwindstack::FrameData frame_data = unwinder->BuildFrameFromPcOnly(frames.get()[i]); frame_data.num = i; _LOG(log, logtype::BACKTRACE, " %s\n", unwinder->FormatFrame(frame_data).c_str()); _LOG(log, logtype::BACKTRACE, " %s\n", unwinder->FormatFrame(frame_data).c_str()); } } } }
libunwindstack/Unwinder.cpp +50 −0 Original line number Original line Diff line number Diff line Loading @@ -395,4 +395,54 @@ bool UnwinderFromPid::Init(ArchEnum arch) { return true; return true; } } FrameData Unwinder::BuildFrameFromPcOnly(uint64_t pc) { FrameData frame; Maps* maps = GetMaps(); MapInfo* map_info = maps->Find(pc); if (!map_info) { frame.rel_pc = pc; return frame; } ArchEnum arch = Regs::CurrentArch(); Elf* elf = map_info->GetElf(GetProcessMemory(), arch); uint64_t relative_pc = elf->GetRelPc(pc, map_info); uint64_t pc_adjustment = GetPcAdjustment(relative_pc, elf, arch); relative_pc -= pc_adjustment; // The debug PC may be different if the PC comes from the JIT. uint64_t debug_pc = relative_pc; // If we don't have a valid ELF file, check the JIT. if (!elf->valid()) { JitDebug jit_debug(GetProcessMemory()); uint64_t jit_pc = pc - pc_adjustment; Elf* jit_elf = jit_debug.GetElf(maps, jit_pc); if (jit_elf != nullptr) { debug_pc = jit_pc; elf = jit_elf; } } // Copy all the things we need into the frame for symbolization. frame.rel_pc = relative_pc; frame.pc = pc - pc_adjustment; frame.map_name = map_info->name; frame.map_elf_start_offset = map_info->elf_start_offset; frame.map_exact_offset = map_info->offset; frame.map_start = map_info->start; frame.map_end = map_info->end; frame.map_flags = map_info->flags; frame.map_load_bias = elf->GetLoadBias(); if (!resolve_names_ || !elf->GetFunctionName(relative_pc, &frame.function_name, &frame.function_offset)) { frame.function_name = ""; frame.function_offset = 0; } return frame; } } // namespace unwindstack } // namespace unwindstack
libunwindstack/include/unwindstack/Unwinder.h +7 −0 Original line number Original line Diff line number Diff line Loading @@ -114,6 +114,13 @@ class Unwinder { ErrorCode LastErrorCode() { return last_error_.code; } ErrorCode LastErrorCode() { return last_error_.code; } uint64_t LastErrorAddress() { return last_error_.address; } uint64_t LastErrorAddress() { return last_error_.address; } // Builds a frame for symbolization using the maps from this unwinder. The // constructed frame contains just enough information to be used to symbolize // frames collected by frame-pointer unwinding that's done outside of // libunwindstack. This is used by tombstoned to symbolize frame pointer-based // stack traces that are collected by tools such as GWP-ASan and MTE. FrameData BuildFrameFromPcOnly(uint64_t pc); protected: protected: Unwinder(size_t max_frames) : max_frames_(max_frames) { frames_.reserve(max_frames); } Unwinder(size_t max_frames) : max_frames_(max_frames) { frames_.reserve(max_frames); } Loading