xref: /aosp_15_r20/external/cronet/base/profiler/native_unwinder_android.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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