Loading libunwindstack/Android.bp +5 −0 Original line number Diff line number Diff line Loading @@ -127,6 +127,10 @@ cc_library { }, }, whole_static_libs: [ "libdemangle" ], static_libs: [ "libprocinfo", ], Loading Loading @@ -189,6 +193,7 @@ cc_test { "tests/MapInfoCreateMemoryTest.cpp", "tests/MapInfoGetElfTest.cpp", "tests/MapInfoGetLoadBiasTest.cpp", "tests/MapInfoTest.cpp", "tests/MapsTest.cpp", "tests/MemoryBufferTest.cpp", "tests/MemoryCacheTest.cpp", Loading libunwindstack/MapInfo.cpp +13 −0 Original line number Diff line number Diff line Loading @@ -221,6 +221,19 @@ Elf* MapInfo::GetElf(const std::shared_ptr<Memory>& process_memory, ArchEnum exp return elf.get(); } bool MapInfo::GetFunctionName(uint64_t addr, std::string* name, uint64_t* func_offset) { { // Make sure no other thread is trying to update this elf object. std::lock_guard<std::mutex> guard(mutex_); if (elf == nullptr) { return false; } } // No longer need the lock, once the elf object is created, it is not deleted // until this object is deleted. return elf->GetFunctionName(addr, name, func_offset); } uint64_t MapInfo::GetLoadBias(const std::shared_ptr<Memory>& process_memory) { uint64_t cur_load_bias = load_bias.load(); if (cur_load_bias != static_cast<uint64_t>(-1)) { Loading libunwindstack/Unwinder.cpp +29 −1 Original line number Diff line number Diff line Loading @@ -26,10 +26,13 @@ #include <android-base/stringprintf.h> #include <demangle.h> #include <unwindstack/Elf.h> #include <unwindstack/JitDebug.h> #include <unwindstack/MapInfo.h> #include <unwindstack/Maps.h> #include <unwindstack/Memory.h> #include <unwindstack/Unwinder.h> #if !defined(NO_LIBDEXFILE_SUPPORT) Loading Loading @@ -306,7 +309,7 @@ std::string Unwinder::FormatFrame(const FrameData& frame, bool is32bit) { } if (!frame.function_name.empty()) { data += " (" + frame.function_name; data += " (" + demangle(frame.function_name.c_str()); if (frame.function_offset != 0) { data += android::base::StringPrintf("+%" PRId64, frame.function_offset); } Loading @@ -327,4 +330,29 @@ void Unwinder::SetDexFiles(DexFiles* dex_files, ArchEnum arch) { } #endif bool UnwinderFromPid::Init(ArchEnum arch) { if (pid_ == getpid()) { maps_ptr_.reset(new LocalMaps()); } else { maps_ptr_.reset(new RemoteMaps(pid_)); } if (!maps_ptr_->Parse()) { return false; } maps_ = maps_ptr_.get(); process_memory_ = Memory::CreateProcessMemoryCached(pid_); jit_debug_ptr_.reset(new JitDebug(process_memory_)); jit_debug_ = jit_debug_ptr_.get(); SetJitDebug(jit_debug_, arch); #if !defined(NO_LIBDEXFILE_SUPPORT) dex_files_ptr_.reset(new DexFiles(process_memory_)); dex_files_ = dex_files_ptr_.get(); SetDexFiles(dex_files_, arch); #endif return true; } } // namespace unwindstack libunwindstack/include/unwindstack/MapInfo.h +2 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,8 @@ struct MapInfo { Memory* CreateMemory(const std::shared_ptr<Memory>& process_memory); bool GetFunctionName(uint64_t addr, std::string* name, uint64_t* func_offset); private: MapInfo(const MapInfo&) = delete; void operator=(const MapInfo&) = delete; Loading libunwindstack/include/unwindstack/Unwinder.h +30 −3 Original line number Diff line number Diff line Loading @@ -24,7 +24,9 @@ #include <string> #include <vector> #include <unwindstack/DexFiles.h> #include <unwindstack/Error.h> #include <unwindstack/JitDebug.h> #include <unwindstack/Maps.h> #include <unwindstack/Memory.h> #include <unwindstack/Regs.h> Loading @@ -32,9 +34,7 @@ namespace unwindstack { // Forward declarations. class DexFiles; class Elf; class JitDebug; enum ArchEnum : uint8_t; struct FrameData { Loading Loading @@ -67,6 +67,11 @@ class Unwinder { : max_frames_(max_frames), maps_(maps), regs_(regs), process_memory_(process_memory) { frames_.reserve(max_frames); } Unwinder(size_t max_frames, Maps* maps, std::shared_ptr<Memory> process_memory) : max_frames_(max_frames), maps_(maps), process_memory_(process_memory) { frames_.reserve(max_frames); } ~Unwinder() = default; void Unwind(const std::vector<std::string>* initial_map_names_to_skip = nullptr, Loading @@ -81,6 +86,10 @@ class Unwinder { void SetJitDebug(JitDebug* jit_debug, ArchEnum arch); void SetRegs(Regs* regs) { regs_ = regs; } Maps* GetMaps() { return maps_; } std::shared_ptr<Memory>& GetProcessMemory() { return process_memory_; } // Disabling the resolving of names results in the function name being // set to an empty string and the function offset being set to zero. void SetResolveNames(bool resolve) { resolve_names_ = resolve; } Loading @@ -92,7 +101,9 @@ class Unwinder { ErrorCode LastErrorCode() { return last_error_.code; } uint64_t LastErrorAddress() { return last_error_.address; } private: protected: Unwinder(size_t max_frames) : max_frames_(max_frames) { frames_.reserve(max_frames); } void FillInDexFrame(); void FillInFrame(MapInfo* map_info, Elf* elf, uint64_t rel_pc, uint64_t func_pc, uint64_t pc_adjustment); Loading @@ -110,6 +121,22 @@ class Unwinder { ErrorData last_error_; }; class UnwinderFromPid : public Unwinder { public: UnwinderFromPid(size_t max_frames, pid_t pid) : Unwinder(max_frames), pid_(pid) {} ~UnwinderFromPid() = default; bool Init(ArchEnum arch); private: pid_t pid_; std::unique_ptr<Maps> maps_ptr_; std::unique_ptr<JitDebug> jit_debug_ptr_; #if !defined(NO_LIBDEXFILE_SUPPORT) std::unique_ptr<DexFiles> dex_files_ptr_; #endif }; } // namespace unwindstack #endif // _LIBUNWINDSTACK_UNWINDER_H Loading
libunwindstack/Android.bp +5 −0 Original line number Diff line number Diff line Loading @@ -127,6 +127,10 @@ cc_library { }, }, whole_static_libs: [ "libdemangle" ], static_libs: [ "libprocinfo", ], Loading Loading @@ -189,6 +193,7 @@ cc_test { "tests/MapInfoCreateMemoryTest.cpp", "tests/MapInfoGetElfTest.cpp", "tests/MapInfoGetLoadBiasTest.cpp", "tests/MapInfoTest.cpp", "tests/MapsTest.cpp", "tests/MemoryBufferTest.cpp", "tests/MemoryCacheTest.cpp", Loading
libunwindstack/MapInfo.cpp +13 −0 Original line number Diff line number Diff line Loading @@ -221,6 +221,19 @@ Elf* MapInfo::GetElf(const std::shared_ptr<Memory>& process_memory, ArchEnum exp return elf.get(); } bool MapInfo::GetFunctionName(uint64_t addr, std::string* name, uint64_t* func_offset) { { // Make sure no other thread is trying to update this elf object. std::lock_guard<std::mutex> guard(mutex_); if (elf == nullptr) { return false; } } // No longer need the lock, once the elf object is created, it is not deleted // until this object is deleted. return elf->GetFunctionName(addr, name, func_offset); } uint64_t MapInfo::GetLoadBias(const std::shared_ptr<Memory>& process_memory) { uint64_t cur_load_bias = load_bias.load(); if (cur_load_bias != static_cast<uint64_t>(-1)) { Loading
libunwindstack/Unwinder.cpp +29 −1 Original line number Diff line number Diff line Loading @@ -26,10 +26,13 @@ #include <android-base/stringprintf.h> #include <demangle.h> #include <unwindstack/Elf.h> #include <unwindstack/JitDebug.h> #include <unwindstack/MapInfo.h> #include <unwindstack/Maps.h> #include <unwindstack/Memory.h> #include <unwindstack/Unwinder.h> #if !defined(NO_LIBDEXFILE_SUPPORT) Loading Loading @@ -306,7 +309,7 @@ std::string Unwinder::FormatFrame(const FrameData& frame, bool is32bit) { } if (!frame.function_name.empty()) { data += " (" + frame.function_name; data += " (" + demangle(frame.function_name.c_str()); if (frame.function_offset != 0) { data += android::base::StringPrintf("+%" PRId64, frame.function_offset); } Loading @@ -327,4 +330,29 @@ void Unwinder::SetDexFiles(DexFiles* dex_files, ArchEnum arch) { } #endif bool UnwinderFromPid::Init(ArchEnum arch) { if (pid_ == getpid()) { maps_ptr_.reset(new LocalMaps()); } else { maps_ptr_.reset(new RemoteMaps(pid_)); } if (!maps_ptr_->Parse()) { return false; } maps_ = maps_ptr_.get(); process_memory_ = Memory::CreateProcessMemoryCached(pid_); jit_debug_ptr_.reset(new JitDebug(process_memory_)); jit_debug_ = jit_debug_ptr_.get(); SetJitDebug(jit_debug_, arch); #if !defined(NO_LIBDEXFILE_SUPPORT) dex_files_ptr_.reset(new DexFiles(process_memory_)); dex_files_ = dex_files_ptr_.get(); SetDexFiles(dex_files_, arch); #endif return true; } } // namespace unwindstack
libunwindstack/include/unwindstack/MapInfo.h +2 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,8 @@ struct MapInfo { Memory* CreateMemory(const std::shared_ptr<Memory>& process_memory); bool GetFunctionName(uint64_t addr, std::string* name, uint64_t* func_offset); private: MapInfo(const MapInfo&) = delete; void operator=(const MapInfo&) = delete; Loading
libunwindstack/include/unwindstack/Unwinder.h +30 −3 Original line number Diff line number Diff line Loading @@ -24,7 +24,9 @@ #include <string> #include <vector> #include <unwindstack/DexFiles.h> #include <unwindstack/Error.h> #include <unwindstack/JitDebug.h> #include <unwindstack/Maps.h> #include <unwindstack/Memory.h> #include <unwindstack/Regs.h> Loading @@ -32,9 +34,7 @@ namespace unwindstack { // Forward declarations. class DexFiles; class Elf; class JitDebug; enum ArchEnum : uint8_t; struct FrameData { Loading Loading @@ -67,6 +67,11 @@ class Unwinder { : max_frames_(max_frames), maps_(maps), regs_(regs), process_memory_(process_memory) { frames_.reserve(max_frames); } Unwinder(size_t max_frames, Maps* maps, std::shared_ptr<Memory> process_memory) : max_frames_(max_frames), maps_(maps), process_memory_(process_memory) { frames_.reserve(max_frames); } ~Unwinder() = default; void Unwind(const std::vector<std::string>* initial_map_names_to_skip = nullptr, Loading @@ -81,6 +86,10 @@ class Unwinder { void SetJitDebug(JitDebug* jit_debug, ArchEnum arch); void SetRegs(Regs* regs) { regs_ = regs; } Maps* GetMaps() { return maps_; } std::shared_ptr<Memory>& GetProcessMemory() { return process_memory_; } // Disabling the resolving of names results in the function name being // set to an empty string and the function offset being set to zero. void SetResolveNames(bool resolve) { resolve_names_ = resolve; } Loading @@ -92,7 +101,9 @@ class Unwinder { ErrorCode LastErrorCode() { return last_error_.code; } uint64_t LastErrorAddress() { return last_error_.address; } private: protected: Unwinder(size_t max_frames) : max_frames_(max_frames) { frames_.reserve(max_frames); } void FillInDexFrame(); void FillInFrame(MapInfo* map_info, Elf* elf, uint64_t rel_pc, uint64_t func_pc, uint64_t pc_adjustment); Loading @@ -110,6 +121,22 @@ class Unwinder { ErrorData last_error_; }; class UnwinderFromPid : public Unwinder { public: UnwinderFromPid(size_t max_frames, pid_t pid) : Unwinder(max_frames), pid_(pid) {} ~UnwinderFromPid() = default; bool Init(ArchEnum arch); private: pid_t pid_; std::unique_ptr<Maps> maps_ptr_; std::unique_ptr<JitDebug> jit_debug_ptr_; #if !defined(NO_LIBDEXFILE_SUPPORT) std::unique_ptr<DexFiles> dex_files_ptr_; #endif }; } // namespace unwindstack #endif // _LIBUNWINDSTACK_UNWINDER_H