Merge changes I3b20be28,I7118025c
* changes:
Revert "init: disable oneshot_on test"
init: require root for oneshot_on test
diff --git a/debuggerd/libdebuggerd/gwp_asan.cpp b/debuggerd/libdebuggerd/gwp_asan.cpp
index 3130cd4..f271365 100644
--- a/debuggerd/libdebuggerd/gwp_asan.cpp
+++ b/debuggerd/libdebuggerd/gwp_asan.cpp
@@ -157,60 +157,6 @@
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;
bool GwpAsanCrashData::HasDeallocationTrace() const {
@@ -237,7 +183,8 @@
unwinder->SetDisplayBuildID(true);
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());
}
}
@@ -263,7 +210,8 @@
unwinder->SetDisplayBuildID(true);
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());
}
}
diff --git a/libunwindstack/Unwinder.cpp b/libunwindstack/Unwinder.cpp
index 560030e..2d867cd 100644
--- a/libunwindstack/Unwinder.cpp
+++ b/libunwindstack/Unwinder.cpp
@@ -395,4 +395,54 @@
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
diff --git a/libunwindstack/include/unwindstack/Unwinder.h b/libunwindstack/include/unwindstack/Unwinder.h
index 67762c0..4d49f23 100644
--- a/libunwindstack/include/unwindstack/Unwinder.h
+++ b/libunwindstack/include/unwindstack/Unwinder.h
@@ -114,6 +114,13 @@
ErrorCode LastErrorCode() { return last_error_.code; }
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:
Unwinder(size_t max_frames) : max_frames_(max_frames) { frames_.reserve(max_frames); }