• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/Memory.h"
14 
15 namespace base {
16 
17 class NativeUnwinderAndroidMapDelegate;
18 class NativeUnwinderAndroidMemoryRegionsMap;
19 
20 // Implementation of unwindstack::Memory that restricts memory access to a stack
21 // buffer, used by NativeUnwinderAndroid. While unwinding, only memory accesses
22 // within the stack should be performed to restore registers.
23 class UnwindStackMemoryAndroid : public unwindstack::Memory {
24  public:
25   UnwindStackMemoryAndroid(uintptr_t stack_ptr, uintptr_t stack_top);
26   ~UnwindStackMemoryAndroid() override;
27 
28   size_t Read(uint64_t addr, void* dst, size_t size) override;
29 
30  private:
31   const uintptr_t stack_ptr_;
32   const uintptr_t stack_top_;
33 };
34 
35 // Native unwinder implementation for Android, using libunwindstack.
36 class NativeUnwinderAndroid : public Unwinder,
37                               public ModuleCache::AuxiliaryModuleProvider {
38  public:
39   // Creates maps object from /proc/self/maps for use by NativeUnwinderAndroid.
40   // Since this is an expensive call, the maps object should be re-used across
41   // all profiles in a process.
42   // Set |use_updatable_maps| to true to use unwindstack::LocalUpdatableMaps,
43   // instead of unwindstack::LocalMaps. LocalUpdatableMaps might be preferable
44   // when the frames come from dynamically added ELFs like JITed ELFs, or
45   // dynamically loaded libraries. With LocalMaps the frames corresponding to
46   // newly loaded ELFs don't get unwound since the existing maps structure
47   // fails to find a map for the given pc while LocalUpdatableMaps reparses
48   // /proc/self/maps when it fails to find a map for the given pc and then can
49   // successfully unwind through newly loaded ELFs as well.
50   static std::unique_ptr<NativeUnwinderAndroidMemoryRegionsMap>
51   CreateMemoryRegionsMap(bool use_updatable_maps = false);
52 
53   // |exclude_module_with_base_address| is used to exclude a specific module and
54   // let another unwinder take control. TryUnwind() will exit with
55   // UNRECOGNIZED_FRAME and CanUnwindFrom() will return false when a frame is
56   // encountered in that module.
57   // |map_delegate| is used to manage memory used by libunwindstack. It must
58   // outlives this object.
59   NativeUnwinderAndroid(uintptr_t exclude_module_with_base_address,
60                         NativeUnwinderAndroidMapDelegate* map_delegate);
61   ~NativeUnwinderAndroid() override;
62 
63   NativeUnwinderAndroid(const NativeUnwinderAndroid&) = delete;
64   NativeUnwinderAndroid& operator=(const NativeUnwinderAndroid&) = delete;
65 
66   // Unwinder
67   void InitializeModules() override;
68   bool CanUnwindFrom(const Frame& current_frame) const override;
69   UnwindResult TryUnwind(RegisterContext* thread_context,
70                          uintptr_t stack_top,
71                          std::vector<Frame>* stack) override;
72 
73   // ModuleCache::AuxiliaryModuleProvider
74   std::unique_ptr<const ModuleCache::Module> TryCreateModuleForAddress(
75       uintptr_t address) override;
76 
77  private:
78   void EmitDexFrame(uintptr_t dex_pc,
79                     std::vector<Frame>* stack) const;
80 
81   const uintptr_t exclude_module_with_base_address_;
82   raw_ptr<NativeUnwinderAndroidMapDelegate> map_delegate_;
83   const raw_ptr<NativeUnwinderAndroidMemoryRegionsMap> memory_regions_map_;
84 };
85 
86 }  // namespace base
87 
88 #endif  // BASE_PROFILER_NATIVE_UNWINDER_ANDROID_H_
89