Loading libbacktrace/UnwindStack.cpp +1 −0 Original line number Original line Diff line number Diff line Loading @@ -50,6 +50,7 @@ bool Backtrace::Unwind(unwindstack::Regs* regs, BacktraceMap* back_map, auto process_memory = stack_map->process_memory(); auto process_memory = stack_map->process_memory(); unwindstack::Unwinder unwinder(MAX_BACKTRACE_FRAMES + num_ignore_frames, stack_map->stack_maps(), unwindstack::Unwinder unwinder(MAX_BACKTRACE_FRAMES + num_ignore_frames, stack_map->stack_maps(), regs, stack_map->process_memory()); regs, stack_map->process_memory()); unwinder.SetJitDebug(stack_map->GetJitDebug(), regs->Arch()); unwinder.Unwind(skip_names, &stack_map->GetSuffixesToIgnore()); unwinder.Unwind(skip_names, &stack_map->GetSuffixesToIgnore()); if (num_ignore_frames >= unwinder.NumFrames()) { if (num_ignore_frames >= unwinder.NumFrames()) { Loading libbacktrace/UnwindStackMap.cpp +7 −0 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,9 @@ #include <stdlib.h> #include <stdlib.h> #include <sys/types.h> #include <sys/types.h> #include <string> #include <vector> #include <backtrace/BacktraceMap.h> #include <backtrace/BacktraceMap.h> #include <unwindstack/Elf.h> #include <unwindstack/Elf.h> #include <unwindstack/MapInfo.h> #include <unwindstack/MapInfo.h> Loading @@ -39,6 +42,10 @@ bool UnwindStackMap::Build() { // Create the process memory object. // Create the process memory object. process_memory_ = unwindstack::Memory::CreateProcessMemory(pid_); process_memory_ = unwindstack::Memory::CreateProcessMemory(pid_); // Create a JitDebug object for getting jit unwind information. std::vector<std::string> search_libs_{"libart.so", "libartd.so"}; jit_debug_.reset(new unwindstack::JitDebug(process_memory_, search_libs_)); if (!stack_maps_->Parse()) { if (!stack_maps_->Parse()) { return false; return false; } } Loading libbacktrace/UnwindStackMap.h +4 −0 Original line number Original line Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <memory> #include <memory> #include <backtrace/BacktraceMap.h> #include <backtrace/BacktraceMap.h> #include <unwindstack/JitDebug.h> #include <unwindstack/Maps.h> #include <unwindstack/Maps.h> class UnwindStackMap : public BacktraceMap { class UnwindStackMap : public BacktraceMap { Loading @@ -41,11 +42,14 @@ class UnwindStackMap : public BacktraceMap { const std::shared_ptr<unwindstack::Memory>& process_memory() { return process_memory_; } const std::shared_ptr<unwindstack::Memory>& process_memory() { return process_memory_; } unwindstack::JitDebug* GetJitDebug() { return jit_debug_.get(); } protected: protected: uint64_t GetLoadBias(size_t index) override; uint64_t GetLoadBias(size_t index) override; std::unique_ptr<unwindstack::Maps> stack_maps_; std::unique_ptr<unwindstack::Maps> stack_maps_; std::shared_ptr<unwindstack::Memory> process_memory_; std::shared_ptr<unwindstack::Memory> process_memory_; std::unique_ptr<unwindstack::JitDebug> jit_debug_; }; }; #endif // _LIBBACKTRACE_UNWINDSTACK_MAP_H #endif // _LIBBACKTRACE_UNWINDSTACK_MAP_H libunwindstack/Android.bp +3 −0 Original line number Original line Diff line number Diff line Loading @@ -55,6 +55,7 @@ cc_library { "Elf.cpp", "Elf.cpp", "ElfInterface.cpp", "ElfInterface.cpp", "ElfInterfaceArm.cpp", "ElfInterfaceArm.cpp", "JitDebug.cpp", "Log.cpp", "Log.cpp", "MapInfo.cpp", "MapInfo.cpp", "Maps.cpp", "Maps.cpp", Loading Loading @@ -128,6 +129,7 @@ cc_test { "tests/ElfInterfaceTest.cpp", "tests/ElfInterfaceTest.cpp", "tests/ElfTest.cpp", "tests/ElfTest.cpp", "tests/ElfTestUtils.cpp", "tests/ElfTestUtils.cpp", "tests/JitDebugTest.cpp", "tests/LogFake.cpp", "tests/LogFake.cpp", "tests/MapInfoGetElfTest.cpp", "tests/MapInfoGetElfTest.cpp", "tests/MapInfoGetLoadBiasTest.cpp", "tests/MapInfoGetLoadBiasTest.cpp", Loading Loading @@ -168,6 +170,7 @@ cc_test { data: [ data: [ "tests/files/elf32.xz", "tests/files/elf32.xz", "tests/files/elf64.xz", "tests/files/elf64.xz", "tests/files/offline/jit_debug_x86_32/*", "tests/files/offline/gnu_debugdata_arm32/*", "tests/files/offline/gnu_debugdata_arm32/*", "tests/files/offline/straddle_arm32/*", "tests/files/offline/straddle_arm32/*", "tests/files/offline/straddle_arm64/*", "tests/files/offline/straddle_arm64/*", Loading libunwindstack/Elf.cpp +48 −0 Original line number Original line Diff line number Diff line Loading @@ -103,6 +103,37 @@ bool Elf::GetFunctionName(uint64_t addr, std::string* name, uint64_t* func_offse addr, load_bias_, name, func_offset))); addr, load_bias_, name, func_offset))); } } bool Elf::GetGlobalVariable(const std::string& name, uint64_t* memory_address) { if (!valid_) { return false; } if (!interface_->GetGlobalVariable(name, memory_address) && (gnu_debugdata_interface_ == nullptr || !gnu_debugdata_interface_->GetGlobalVariable(name, memory_address))) { return false; } // Adjust by the load bias. if (*memory_address < load_bias_) { return false; } *memory_address -= load_bias_; // If this winds up in the dynamic section, then we might need to adjust // the address. uint64_t dynamic_end = interface_->dynamic_vaddr() + interface_->dynamic_size(); if (*memory_address >= interface_->dynamic_vaddr() && *memory_address < dynamic_end) { if (interface_->dynamic_vaddr() > interface_->dynamic_offset()) { *memory_address -= interface_->dynamic_vaddr() - interface_->dynamic_offset(); } else { *memory_address += interface_->dynamic_offset() - interface_->dynamic_vaddr(); } } return true; } // The relative pc is always relative to the start of the map from which it comes. // The relative pc is always relative to the start of the map from which it comes. bool Elf::Step(uint64_t rel_pc, uint64_t adjusted_rel_pc, uint64_t elf_offset, Regs* regs, bool Elf::Step(uint64_t rel_pc, uint64_t adjusted_rel_pc, uint64_t elf_offset, Regs* regs, Memory* process_memory, bool* finished) { Memory* process_memory, bool* finished) { Loading Loading @@ -160,6 +191,23 @@ void Elf::GetInfo(Memory* memory, bool* valid, uint64_t* size) { } } } } bool Elf::IsValidPc(uint64_t pc) { if (!valid_ || pc < load_bias_) { return false; } pc -= load_bias_; if (interface_->IsValidPc(pc)) { return true; } if (gnu_debugdata_interface_ != nullptr && gnu_debugdata_interface_->IsValidPc(pc)) { return true; } return false; } ElfInterface* Elf::CreateInterfaceFromMemory(Memory* memory) { ElfInterface* Elf::CreateInterfaceFromMemory(Memory* memory) { if (!IsValidElf(memory)) { if (!IsValidElf(memory)) { return nullptr; return nullptr; Loading Loading
libbacktrace/UnwindStack.cpp +1 −0 Original line number Original line Diff line number Diff line Loading @@ -50,6 +50,7 @@ bool Backtrace::Unwind(unwindstack::Regs* regs, BacktraceMap* back_map, auto process_memory = stack_map->process_memory(); auto process_memory = stack_map->process_memory(); unwindstack::Unwinder unwinder(MAX_BACKTRACE_FRAMES + num_ignore_frames, stack_map->stack_maps(), unwindstack::Unwinder unwinder(MAX_BACKTRACE_FRAMES + num_ignore_frames, stack_map->stack_maps(), regs, stack_map->process_memory()); regs, stack_map->process_memory()); unwinder.SetJitDebug(stack_map->GetJitDebug(), regs->Arch()); unwinder.Unwind(skip_names, &stack_map->GetSuffixesToIgnore()); unwinder.Unwind(skip_names, &stack_map->GetSuffixesToIgnore()); if (num_ignore_frames >= unwinder.NumFrames()) { if (num_ignore_frames >= unwinder.NumFrames()) { Loading
libbacktrace/UnwindStackMap.cpp +7 −0 Original line number Original line Diff line number Diff line Loading @@ -18,6 +18,9 @@ #include <stdlib.h> #include <stdlib.h> #include <sys/types.h> #include <sys/types.h> #include <string> #include <vector> #include <backtrace/BacktraceMap.h> #include <backtrace/BacktraceMap.h> #include <unwindstack/Elf.h> #include <unwindstack/Elf.h> #include <unwindstack/MapInfo.h> #include <unwindstack/MapInfo.h> Loading @@ -39,6 +42,10 @@ bool UnwindStackMap::Build() { // Create the process memory object. // Create the process memory object. process_memory_ = unwindstack::Memory::CreateProcessMemory(pid_); process_memory_ = unwindstack::Memory::CreateProcessMemory(pid_); // Create a JitDebug object for getting jit unwind information. std::vector<std::string> search_libs_{"libart.so", "libartd.so"}; jit_debug_.reset(new unwindstack::JitDebug(process_memory_, search_libs_)); if (!stack_maps_->Parse()) { if (!stack_maps_->Parse()) { return false; return false; } } Loading
libbacktrace/UnwindStackMap.h +4 −0 Original line number Original line Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include <memory> #include <memory> #include <backtrace/BacktraceMap.h> #include <backtrace/BacktraceMap.h> #include <unwindstack/JitDebug.h> #include <unwindstack/Maps.h> #include <unwindstack/Maps.h> class UnwindStackMap : public BacktraceMap { class UnwindStackMap : public BacktraceMap { Loading @@ -41,11 +42,14 @@ class UnwindStackMap : public BacktraceMap { const std::shared_ptr<unwindstack::Memory>& process_memory() { return process_memory_; } const std::shared_ptr<unwindstack::Memory>& process_memory() { return process_memory_; } unwindstack::JitDebug* GetJitDebug() { return jit_debug_.get(); } protected: protected: uint64_t GetLoadBias(size_t index) override; uint64_t GetLoadBias(size_t index) override; std::unique_ptr<unwindstack::Maps> stack_maps_; std::unique_ptr<unwindstack::Maps> stack_maps_; std::shared_ptr<unwindstack::Memory> process_memory_; std::shared_ptr<unwindstack::Memory> process_memory_; std::unique_ptr<unwindstack::JitDebug> jit_debug_; }; }; #endif // _LIBBACKTRACE_UNWINDSTACK_MAP_H #endif // _LIBBACKTRACE_UNWINDSTACK_MAP_H
libunwindstack/Android.bp +3 −0 Original line number Original line Diff line number Diff line Loading @@ -55,6 +55,7 @@ cc_library { "Elf.cpp", "Elf.cpp", "ElfInterface.cpp", "ElfInterface.cpp", "ElfInterfaceArm.cpp", "ElfInterfaceArm.cpp", "JitDebug.cpp", "Log.cpp", "Log.cpp", "MapInfo.cpp", "MapInfo.cpp", "Maps.cpp", "Maps.cpp", Loading Loading @@ -128,6 +129,7 @@ cc_test { "tests/ElfInterfaceTest.cpp", "tests/ElfInterfaceTest.cpp", "tests/ElfTest.cpp", "tests/ElfTest.cpp", "tests/ElfTestUtils.cpp", "tests/ElfTestUtils.cpp", "tests/JitDebugTest.cpp", "tests/LogFake.cpp", "tests/LogFake.cpp", "tests/MapInfoGetElfTest.cpp", "tests/MapInfoGetElfTest.cpp", "tests/MapInfoGetLoadBiasTest.cpp", "tests/MapInfoGetLoadBiasTest.cpp", Loading Loading @@ -168,6 +170,7 @@ cc_test { data: [ data: [ "tests/files/elf32.xz", "tests/files/elf32.xz", "tests/files/elf64.xz", "tests/files/elf64.xz", "tests/files/offline/jit_debug_x86_32/*", "tests/files/offline/gnu_debugdata_arm32/*", "tests/files/offline/gnu_debugdata_arm32/*", "tests/files/offline/straddle_arm32/*", "tests/files/offline/straddle_arm32/*", "tests/files/offline/straddle_arm64/*", "tests/files/offline/straddle_arm64/*", Loading
libunwindstack/Elf.cpp +48 −0 Original line number Original line Diff line number Diff line Loading @@ -103,6 +103,37 @@ bool Elf::GetFunctionName(uint64_t addr, std::string* name, uint64_t* func_offse addr, load_bias_, name, func_offset))); addr, load_bias_, name, func_offset))); } } bool Elf::GetGlobalVariable(const std::string& name, uint64_t* memory_address) { if (!valid_) { return false; } if (!interface_->GetGlobalVariable(name, memory_address) && (gnu_debugdata_interface_ == nullptr || !gnu_debugdata_interface_->GetGlobalVariable(name, memory_address))) { return false; } // Adjust by the load bias. if (*memory_address < load_bias_) { return false; } *memory_address -= load_bias_; // If this winds up in the dynamic section, then we might need to adjust // the address. uint64_t dynamic_end = interface_->dynamic_vaddr() + interface_->dynamic_size(); if (*memory_address >= interface_->dynamic_vaddr() && *memory_address < dynamic_end) { if (interface_->dynamic_vaddr() > interface_->dynamic_offset()) { *memory_address -= interface_->dynamic_vaddr() - interface_->dynamic_offset(); } else { *memory_address += interface_->dynamic_offset() - interface_->dynamic_vaddr(); } } return true; } // The relative pc is always relative to the start of the map from which it comes. // The relative pc is always relative to the start of the map from which it comes. bool Elf::Step(uint64_t rel_pc, uint64_t adjusted_rel_pc, uint64_t elf_offset, Regs* regs, bool Elf::Step(uint64_t rel_pc, uint64_t adjusted_rel_pc, uint64_t elf_offset, Regs* regs, Memory* process_memory, bool* finished) { Memory* process_memory, bool* finished) { Loading Loading @@ -160,6 +191,23 @@ void Elf::GetInfo(Memory* memory, bool* valid, uint64_t* size) { } } } } bool Elf::IsValidPc(uint64_t pc) { if (!valid_ || pc < load_bias_) { return false; } pc -= load_bias_; if (interface_->IsValidPc(pc)) { return true; } if (gnu_debugdata_interface_ != nullptr && gnu_debugdata_interface_->IsValidPc(pc)) { return true; } return false; } ElfInterface* Elf::CreateInterfaceFromMemory(Memory* memory) { ElfInterface* Elf::CreateInterfaceFromMemory(Memory* memory) { if (!IsValidElf(memory)) { if (!IsValidElf(memory)) { return nullptr; return nullptr; Loading