1 // Copyright 2019 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_PROFILER_NATIVE_UNWINDER_ANDROID_H_ 6 #define BASE_PROFILER_NATIVE_UNWINDER_ANDROID_H_ 7 8 #include <memory> 9 #include <vector> 10 11 #include "base/memory/raw_ptr.h" 12 #include "base/profiler/unwinder.h" 13 #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/DexFiles.h" 14 #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/Memory.h" 15 16 namespace base { 17 18 class NativeUnwinderAndroidMapDelegate; 19 class NativeUnwinderAndroidMemoryRegionsMap; 20 class NativeUnwinderAndroidMemoryRegionsMapImpl; 21 22 // Implementation of unwindstack::Memory that restricts memory access to a stack 23 // buffer, used by NativeUnwinderAndroid. While unwinding, only memory accesses 24 // within the stack should be performed to restore registers. 25 class UnwindStackMemoryAndroid : public unwindstack::Memory { 26 public: 27 UnwindStackMemoryAndroid(uintptr_t stack_ptr, uintptr_t stack_top); 28 ~UnwindStackMemoryAndroid() override; 29 30 size_t Read(uint64_t addr, void* dst, size_t size) override; 31 32 private: 33 const uintptr_t stack_ptr_; 34 const uintptr_t stack_top_; 35 }; 36 37 // Native unwinder implementation for Android, using libunwindstack. 38 class NativeUnwinderAndroid : public Unwinder, 39 public ModuleCache::AuxiliaryModuleProvider { 40 public: 41 // Creates maps object from /proc/self/maps for use by NativeUnwinderAndroid. 42 // Since this is an expensive call, the maps object should be re-used across 43 // all profiles in a process. 44 // Set |use_updatable_maps| to true to use unwindstack::LocalUpdatableMaps, 45 // instead of unwindstack::LocalMaps. LocalUpdatableMaps might be preferable 46 // when the frames come from dynamically added ELFs like JITed ELFs, or 47 // dynamically loaded libraries. With LocalMaps the frames corresponding to 48 // newly loaded ELFs don't get unwound since the existing maps structure 49 // fails to find a map for the given pc while LocalUpdatableMaps reparses 50 // /proc/self/maps when it fails to find a map for the given pc and then can 51 // successfully unwind through newly loaded ELFs as well. 52 static std::unique_ptr<NativeUnwinderAndroidMemoryRegionsMap> 53 CreateMemoryRegionsMap(bool use_updatable_maps = false); 54 55 // |exclude_module_with_base_address| is used to exclude a specific module and 56 // let another unwinder take control. TryUnwind() will exit with 57 // UNRECOGNIZED_FRAME and CanUnwindFrom() will return false when a frame is 58 // encountered in that module. 59 // |map_delegate| is used to manage memory used by libunwindstack. It must 60 // outlives this object. 61 NativeUnwinderAndroid(uintptr_t exclude_module_with_base_address, 62 NativeUnwinderAndroidMapDelegate* map_delegate, 63 bool is_java_name_hashing_enabled); 64 ~NativeUnwinderAndroid() override; 65 66 NativeUnwinderAndroid(const NativeUnwinderAndroid&) = delete; 67 NativeUnwinderAndroid& operator=(const NativeUnwinderAndroid&) = delete; 68 69 // Unwinder 70 void InitializeModules() override; 71 bool CanUnwindFrom(const Frame& current_frame) const override; 72 UnwindResult TryUnwind(RegisterContext* thread_context, 73 uintptr_t stack_top, 74 std::vector<Frame>* stack) override; 75 76 // ModuleCache::AuxiliaryModuleProvider 77 std::unique_ptr<const ModuleCache::Module> TryCreateModuleForAddress( 78 uintptr_t address) override; 79 80 private: 81 unwindstack::DexFiles* GetOrCreateDexFiles(unwindstack::ArchEnum arch); 82 83 void EmitDexFrame(uintptr_t dex_pc, 84 unwindstack::ArchEnum, 85 std::vector<Frame>* stack); 86 87 const bool is_java_name_hashing_enabled_; 88 std::unique_ptr<unwindstack::DexFiles> dex_files_; 89 90 const uintptr_t exclude_module_with_base_address_; 91 raw_ptr<NativeUnwinderAndroidMapDelegate> map_delegate_; 92 const raw_ptr<NativeUnwinderAndroidMemoryRegionsMapImpl> memory_regions_map_; 93 // This is a vector (rather than an array) because it gets used in functions 94 // from libunwindstack. 95 const std::vector<std::string> search_libs_ = {"libart.so", "libartd.so"}; 96 }; 97 98 } // namespace base 99 100 #endif // BASE_PROFILER_NATIVE_UNWINDER_ANDROID_H_ 101