Loading libbacktrace/UnwindStack.cpp +6 −28 Original line number Diff line number Diff line Loading @@ -43,29 +43,7 @@ #include "UnwindStack.h" #include "UnwindStackMap.h" static std::string GetFunctionName(BacktraceMap* back_map, uintptr_t pc, uintptr_t* offset) { *offset = 0; unwindstack::Maps* maps = reinterpret_cast<UnwindStackMap*>(back_map)->stack_maps(); // Get the map for this unwindstack::MapInfo* map_info = maps->Find(pc); if (map_info == nullptr || map_info->flags & PROT_DEVICE_MAP) { return ""; } UnwindStackMap* stack_map = reinterpret_cast<UnwindStackMap*>(back_map); unwindstack::Elf* elf = map_info->GetElf(stack_map->process_memory(), true); std::string name; uint64_t func_offset; if (!elf->GetFunctionName(elf->GetRelPc(pc, map_info), &name, &func_offset)) { return ""; } *offset = func_offset; return name; } static bool Unwind(unwindstack::Regs* regs, BacktraceMap* back_map, bool Backtrace::Unwind(unwindstack::Regs* regs, BacktraceMap* back_map, std::vector<backtrace_frame_data_t>* frames, size_t num_ignore_frames) { static std::set<std::string> skip_names{"libunwindstack.so", "libbacktrace.so"}; UnwindStackMap* stack_map = reinterpret_cast<UnwindStackMap*>(back_map); Loading Loading @@ -110,7 +88,7 @@ UnwindStackCurrent::UnwindStackCurrent(pid_t pid, pid_t tid, BacktraceMap* map) : BacktraceCurrent(pid, tid, map) {} std::string UnwindStackCurrent::GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) { return ::GetFunctionName(GetMap(), pc, offset); return GetMap()->GetFunctionName(pc, offset); } bool UnwindStackCurrent::UnwindFromContext(size_t num_ignore_frames, ucontext_t* ucontext) { Loading @@ -126,14 +104,14 @@ bool UnwindStackCurrent::UnwindFromContext(size_t num_ignore_frames, ucontext_t* } error_ = BACKTRACE_UNWIND_NO_ERROR; return ::Unwind(regs.get(), GetMap(), &frames_, num_ignore_frames); return Backtrace::Unwind(regs.get(), GetMap(), &frames_, num_ignore_frames); } UnwindStackPtrace::UnwindStackPtrace(pid_t pid, pid_t tid, BacktraceMap* map) : BacktracePtrace(pid, tid, map) {} std::string UnwindStackPtrace::GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) { return ::GetFunctionName(GetMap(), pc, offset); return GetMap()->GetFunctionName(pc, offset); } bool UnwindStackPtrace::Unwind(size_t num_ignore_frames, ucontext_t* context) { Loading @@ -146,5 +124,5 @@ bool UnwindStackPtrace::Unwind(size_t num_ignore_frames, ucontext_t* context) { } error_ = BACKTRACE_UNWIND_NO_ERROR; return ::Unwind(regs.get(), GetMap(), &frames_, num_ignore_frames); return Backtrace::Unwind(regs.get(), GetMap(), &frames_, num_ignore_frames); } libbacktrace/UnwindStackMap.cpp +25 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,31 @@ void UnwindStackMap::FillIn(uintptr_t addr, backtrace_map_t* map) { map->load_bias = elf->GetLoadBias(); } std::string UnwindStackMap::GetFunctionName(uintptr_t pc, uintptr_t* offset) { *offset = 0; unwindstack::Maps* maps = stack_maps(); // Get the map for this unwindstack::MapInfo* map_info = maps->Find(pc); if (map_info == nullptr || map_info->flags & PROT_DEVICE_MAP) { return ""; } unwindstack::Elf* elf = map_info->GetElf(process_memory(), true); std::string name; uint64_t func_offset; if (!elf->GetFunctionName(elf->GetRelPc(pc, map_info), &name, &func_offset)) { return ""; } *offset = func_offset; return name; } std::shared_ptr<unwindstack::Memory> UnwindStackMap::GetProcessMemory() { return process_memory_; } //------------------------------------------------------------------------- // BacktraceMap create function. //------------------------------------------------------------------------- Loading libbacktrace/UnwindStackMap.h +3 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,9 @@ class UnwindStackMap : public BacktraceMap { void FillIn(uintptr_t addr, backtrace_map_t* map) override; virtual std::string GetFunctionName(uintptr_t pc, uintptr_t* offset) override; virtual std::shared_ptr<unwindstack::Memory> GetProcessMemory() override final; unwindstack::Maps* stack_maps() { return stack_maps_.get(); } const std::shared_ptr<unwindstack::Memory>& process_memory() { return process_memory_; } Loading libbacktrace/include/backtrace/Backtrace.h +7 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,10 @@ struct backtrace_stackinfo_t { const uint8_t* data; }; namespace unwindstack { class Regs; } class Backtrace { public: // Create the correct Backtrace object based on what is to be unwound. Loading Loading @@ -106,6 +110,9 @@ public: // Get the current stack trace and store in the backtrace_ structure. virtual bool Unwind(size_t num_ignore_frames, ucontext_t* context = NULL) = 0; static bool Unwind(unwindstack::Regs* regs, BacktraceMap* back_map, std::vector<backtrace_frame_data_t>* frames, size_t num_ignore_frames); // Get the function name and offset into the function given the pc. // If the string is empty, then no valid function name was found, // or the pc is not in any valid map. Loading libbacktrace/include/backtrace/BacktraceMap.h +8 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,10 @@ struct backtrace_map_t { std::string name; }; namespace unwindstack { class Memory; } class BacktraceMap { public: // If uncached is true, then parse the current process map as of the call. Loading @@ -62,6 +66,10 @@ public: // Fill in the map data structure for the given address. virtual void FillIn(uintptr_t addr, backtrace_map_t* map); // Only supported with the new unwinder. virtual std::string GetFunctionName(uintptr_t /*pc*/, uintptr_t* /*offset*/) { return ""; } virtual std::shared_ptr<unwindstack::Memory> GetProcessMemory() { return nullptr; } // The flags returned are the same flags as used by the mmap call. // The values are PROT_*. int GetFlags(uintptr_t pc) { Loading Loading
libbacktrace/UnwindStack.cpp +6 −28 Original line number Diff line number Diff line Loading @@ -43,29 +43,7 @@ #include "UnwindStack.h" #include "UnwindStackMap.h" static std::string GetFunctionName(BacktraceMap* back_map, uintptr_t pc, uintptr_t* offset) { *offset = 0; unwindstack::Maps* maps = reinterpret_cast<UnwindStackMap*>(back_map)->stack_maps(); // Get the map for this unwindstack::MapInfo* map_info = maps->Find(pc); if (map_info == nullptr || map_info->flags & PROT_DEVICE_MAP) { return ""; } UnwindStackMap* stack_map = reinterpret_cast<UnwindStackMap*>(back_map); unwindstack::Elf* elf = map_info->GetElf(stack_map->process_memory(), true); std::string name; uint64_t func_offset; if (!elf->GetFunctionName(elf->GetRelPc(pc, map_info), &name, &func_offset)) { return ""; } *offset = func_offset; return name; } static bool Unwind(unwindstack::Regs* regs, BacktraceMap* back_map, bool Backtrace::Unwind(unwindstack::Regs* regs, BacktraceMap* back_map, std::vector<backtrace_frame_data_t>* frames, size_t num_ignore_frames) { static std::set<std::string> skip_names{"libunwindstack.so", "libbacktrace.so"}; UnwindStackMap* stack_map = reinterpret_cast<UnwindStackMap*>(back_map); Loading Loading @@ -110,7 +88,7 @@ UnwindStackCurrent::UnwindStackCurrent(pid_t pid, pid_t tid, BacktraceMap* map) : BacktraceCurrent(pid, tid, map) {} std::string UnwindStackCurrent::GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) { return ::GetFunctionName(GetMap(), pc, offset); return GetMap()->GetFunctionName(pc, offset); } bool UnwindStackCurrent::UnwindFromContext(size_t num_ignore_frames, ucontext_t* ucontext) { Loading @@ -126,14 +104,14 @@ bool UnwindStackCurrent::UnwindFromContext(size_t num_ignore_frames, ucontext_t* } error_ = BACKTRACE_UNWIND_NO_ERROR; return ::Unwind(regs.get(), GetMap(), &frames_, num_ignore_frames); return Backtrace::Unwind(regs.get(), GetMap(), &frames_, num_ignore_frames); } UnwindStackPtrace::UnwindStackPtrace(pid_t pid, pid_t tid, BacktraceMap* map) : BacktracePtrace(pid, tid, map) {} std::string UnwindStackPtrace::GetFunctionNameRaw(uintptr_t pc, uintptr_t* offset) { return ::GetFunctionName(GetMap(), pc, offset); return GetMap()->GetFunctionName(pc, offset); } bool UnwindStackPtrace::Unwind(size_t num_ignore_frames, ucontext_t* context) { Loading @@ -146,5 +124,5 @@ bool UnwindStackPtrace::Unwind(size_t num_ignore_frames, ucontext_t* context) { } error_ = BACKTRACE_UNWIND_NO_ERROR; return ::Unwind(regs.get(), GetMap(), &frames_, num_ignore_frames); return Backtrace::Unwind(regs.get(), GetMap(), &frames_, num_ignore_frames); }
libbacktrace/UnwindStackMap.cpp +25 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,31 @@ void UnwindStackMap::FillIn(uintptr_t addr, backtrace_map_t* map) { map->load_bias = elf->GetLoadBias(); } std::string UnwindStackMap::GetFunctionName(uintptr_t pc, uintptr_t* offset) { *offset = 0; unwindstack::Maps* maps = stack_maps(); // Get the map for this unwindstack::MapInfo* map_info = maps->Find(pc); if (map_info == nullptr || map_info->flags & PROT_DEVICE_MAP) { return ""; } unwindstack::Elf* elf = map_info->GetElf(process_memory(), true); std::string name; uint64_t func_offset; if (!elf->GetFunctionName(elf->GetRelPc(pc, map_info), &name, &func_offset)) { return ""; } *offset = func_offset; return name; } std::shared_ptr<unwindstack::Memory> UnwindStackMap::GetProcessMemory() { return process_memory_; } //------------------------------------------------------------------------- // BacktraceMap create function. //------------------------------------------------------------------------- Loading
libbacktrace/UnwindStackMap.h +3 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,9 @@ class UnwindStackMap : public BacktraceMap { void FillIn(uintptr_t addr, backtrace_map_t* map) override; virtual std::string GetFunctionName(uintptr_t pc, uintptr_t* offset) override; virtual std::shared_ptr<unwindstack::Memory> GetProcessMemory() override final; unwindstack::Maps* stack_maps() { return stack_maps_.get(); } const std::shared_ptr<unwindstack::Memory>& process_memory() { return process_memory_; } Loading
libbacktrace/include/backtrace/Backtrace.h +7 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,10 @@ struct backtrace_stackinfo_t { const uint8_t* data; }; namespace unwindstack { class Regs; } class Backtrace { public: // Create the correct Backtrace object based on what is to be unwound. Loading Loading @@ -106,6 +110,9 @@ public: // Get the current stack trace and store in the backtrace_ structure. virtual bool Unwind(size_t num_ignore_frames, ucontext_t* context = NULL) = 0; static bool Unwind(unwindstack::Regs* regs, BacktraceMap* back_map, std::vector<backtrace_frame_data_t>* frames, size_t num_ignore_frames); // Get the function name and offset into the function given the pc. // If the string is empty, then no valid function name was found, // or the pc is not in any valid map. Loading
libbacktrace/include/backtrace/BacktraceMap.h +8 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,10 @@ struct backtrace_map_t { std::string name; }; namespace unwindstack { class Memory; } class BacktraceMap { public: // If uncached is true, then parse the current process map as of the call. Loading @@ -62,6 +66,10 @@ public: // Fill in the map data structure for the given address. virtual void FillIn(uintptr_t addr, backtrace_map_t* map); // Only supported with the new unwinder. virtual std::string GetFunctionName(uintptr_t /*pc*/, uintptr_t* /*offset*/) { return ""; } virtual std::shared_ptr<unwindstack::Memory> GetProcessMemory() { return nullptr; } // The flags returned are the same flags as used by the mmap call. // The values are PROT_*. int GetFlags(uintptr_t pc) { Loading