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 #include "base/profiler/native_unwinder_android.h"
6
7 #include <sys/mman.h>
8
9 #include <string>
10 #include <vector>
11
12 #include "base/memory/ptr_util.h"
13 #include "base/metrics/histogram_macros.h"
14 #include "base/metrics/metrics_hashes.h"
15 #include "base/notreached.h"
16 #include "base/profiler/module_cache.h"
17 #include "base/profiler/native_unwinder_android_map_delegate.h"
18 #include "base/profiler/native_unwinder_android_memory_regions_map_impl.h"
19 #include "base/profiler/profile_builder.h"
20 #include "build/build_config.h"
21 #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/Elf.h"
22 #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/Maps.h"
23 #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/Memory.h"
24 #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/Regs.h"
25
26 #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
27 #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/MachineArm.h"
28 #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/RegsArm.h"
29 #elif defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_64_BITS)
30 #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/MachineArm64.h"
31 #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/RegsArm64.h"
32 #endif // #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
33
34 namespace base {
35 namespace {
36
37 class NonElfModule : public ModuleCache::Module {
38 public:
NonElfModule(unwindstack::MapInfo * map_info)39 explicit NonElfModule(unwindstack::MapInfo* map_info)
40 : start_(map_info->start()),
41 size_(map_info->end() - start_),
42 map_info_name_(map_info->name()) {}
43 ~NonElfModule() override = default;
44
GetBaseAddress() const45 uintptr_t GetBaseAddress() const override { return start_; }
46
GetId() const47 std::string GetId() const override { return ""; }
48
GetDebugBasename() const49 FilePath GetDebugBasename() const override {
50 return FilePath(map_info_name_);
51 }
52
53 // Gets the size of the module.
GetSize() const54 size_t GetSize() const override { return size_; }
55
56 // True if this is a native module.
IsNative() const57 bool IsNative() const override { return true; }
58
59 private:
60 const uintptr_t start_;
61 const size_t size_;
62 const std::string map_info_name_;
63 };
64
CreateFromRegisterContext(RegisterContext * thread_context)65 std::unique_ptr<unwindstack::Regs> CreateFromRegisterContext(
66 RegisterContext* thread_context) {
67 #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
68 return WrapUnique<unwindstack::Regs>(unwindstack::RegsArm::Read(
69 reinterpret_cast<void*>(&thread_context->arm_r0)));
70 #elif defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_64_BITS)
71 return WrapUnique<unwindstack::Regs>(unwindstack::RegsArm64::Read(
72 reinterpret_cast<void*>(&thread_context->regs[0])));
73 #else // #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
74 NOTREACHED();
75 #endif // #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
76 }
77
CopyToRegisterContext(unwindstack::Regs * regs,RegisterContext * thread_context)78 void CopyToRegisterContext(unwindstack::Regs* regs,
79 RegisterContext* thread_context) {
80 #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
81 memcpy(reinterpret_cast<void*>(&thread_context->arm_r0), regs->RawData(),
82 unwindstack::ARM_REG_LAST * sizeof(uintptr_t));
83 #elif defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_64_BITS)
84 memcpy(reinterpret_cast<void*>(&thread_context->regs[0]), regs->RawData(),
85 unwindstack::ARM64_REG_LAST * sizeof(uintptr_t));
86 #else // #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
87 NOTREACHED();
88 #endif // #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
89 }
90
91 } // namespace
92
UnwindStackMemoryAndroid(uintptr_t stack_ptr,uintptr_t stack_top)93 UnwindStackMemoryAndroid::UnwindStackMemoryAndroid(uintptr_t stack_ptr,
94 uintptr_t stack_top)
95 : stack_ptr_(stack_ptr), stack_top_(stack_top) {
96 DCHECK_LE(stack_ptr_, stack_top_);
97 }
98
99 UnwindStackMemoryAndroid::~UnwindStackMemoryAndroid() = default;
100
Read(uint64_t addr,void * dst,size_t size)101 size_t UnwindStackMemoryAndroid::Read(uint64_t addr, void* dst, size_t size) {
102 if (addr < stack_ptr_)
103 return 0;
104 if (size >= stack_top_ || addr > stack_top_ - size)
105 return 0;
106 memcpy(dst, reinterpret_cast<void*>(addr), size);
107 return size;
108 }
109
110 // static
111 std::unique_ptr<NativeUnwinderAndroidMemoryRegionsMap>
CreateMemoryRegionsMap(bool use_updatable_maps)112 NativeUnwinderAndroid::CreateMemoryRegionsMap(bool use_updatable_maps) {
113 std::unique_ptr<unwindstack::Maps> maps;
114 if (use_updatable_maps) {
115 maps = std::make_unique<unwindstack::LocalUpdatableMaps>();
116 } else {
117 maps = std::make_unique<unwindstack::LocalMaps>();
118 }
119 const bool success = maps->Parse();
120 DCHECK(success);
121
122 return std::make_unique<NativeUnwinderAndroidMemoryRegionsMapImpl>(
123 std::move(maps), unwindstack::Memory::CreateLocalProcessMemory());
124 }
125
NativeUnwinderAndroid(uintptr_t exclude_module_with_base_address,NativeUnwinderAndroidMapDelegate * map_delegate)126 NativeUnwinderAndroid::NativeUnwinderAndroid(
127 uintptr_t exclude_module_with_base_address,
128 NativeUnwinderAndroidMapDelegate* map_delegate)
129 : exclude_module_with_base_address_(exclude_module_with_base_address),
130 map_delegate_(map_delegate),
131 memory_regions_map_(
132 static_cast<NativeUnwinderAndroidMemoryRegionsMapImpl*>(
133 map_delegate->GetMapReference())) {
134 DCHECK(map_delegate_);
135 DCHECK(memory_regions_map_);
136 }
137
~NativeUnwinderAndroid()138 NativeUnwinderAndroid::~NativeUnwinderAndroid() {
139 if (module_cache())
140 module_cache()->UnregisterAuxiliaryModuleProvider(this);
141
142 map_delegate_->ReleaseMapReference();
143 }
144
InitializeModules()145 void NativeUnwinderAndroid::InitializeModules() {
146 module_cache()->RegisterAuxiliaryModuleProvider(this);
147 }
148
CanUnwindFrom(const Frame & current_frame) const149 bool NativeUnwinderAndroid::CanUnwindFrom(const Frame& current_frame) const {
150 return current_frame.module && current_frame.module->IsNative() &&
151 current_frame.module->GetBaseAddress() !=
152 exclude_module_with_base_address_;
153 }
154
TryUnwind(UnwinderStateCapture * capture_state,RegisterContext * thread_context,uintptr_t stack_top,std::vector<Frame> * stack)155 UnwindResult NativeUnwinderAndroid::TryUnwind(
156 UnwinderStateCapture* capture_state,
157 RegisterContext* thread_context,
158 uintptr_t stack_top,
159 std::vector<Frame>* stack) {
160 auto regs = CreateFromRegisterContext(thread_context);
161 DCHECK(regs);
162 unwindstack::ArchEnum arch = regs->Arch();
163
164 do {
165 uint64_t cur_pc = regs->pc();
166 uint64_t cur_sp = regs->sp();
167 unwindstack::MapInfo* map_info =
168 memory_regions_map_->maps()->Find(cur_pc).get();
169 if (map_info == nullptr ||
170 map_info->flags() & unwindstack::MAPS_FLAGS_DEVICE_MAP) {
171 break;
172 }
173
174 unwindstack::Elf* elf =
175 map_info->GetElf(memory_regions_map_->memory(), arch);
176 if (!elf->valid())
177 break;
178
179 UnwindStackMemoryAndroid stack_memory(cur_sp, stack_top);
180 uintptr_t rel_pc = elf->GetRelPc(cur_pc, map_info);
181 bool is_signal_frame = false;
182 bool finished = false;
183 // map_info->GetElf() may return a valid elf whose memory() is nullptr.
184 // In the case, elf->StepIfSignalHandler() and elf->Step() are not
185 // available, because the method depends on elf->memory().
186 // (Regarding Step(), EvalRegister() needs memory.)
187 bool stepped =
188 elf->memory() &&
189 (elf->StepIfSignalHandler(rel_pc, regs.get(), &stack_memory) ||
190 elf->Step(rel_pc, regs.get(), &stack_memory, &finished,
191 &is_signal_frame));
192 if (stepped && finished)
193 return UnwindResult::kCompleted;
194
195 if (!stepped) {
196 // Stepping failed. Try unwinding using return address.
197 if (stack->size() == 1) {
198 if (!regs->SetPcFromReturnAddress(&stack_memory))
199 return UnwindResult::kAborted;
200 } else {
201 break;
202 }
203 }
204
205 // If the pc and sp didn't change, then consider everything stopped.
206 if (cur_pc == regs->pc() && cur_sp == regs->sp())
207 return UnwindResult::kAborted;
208
209 // Exclusive range of expected stack pointer values after the unwind.
210 struct {
211 uintptr_t start;
212 uintptr_t end;
213 } expected_stack_pointer_range = {static_cast<uintptr_t>(cur_sp),
214 stack_top};
215 if (regs->sp() < expected_stack_pointer_range.start ||
216 regs->sp() >= expected_stack_pointer_range.end) {
217 return UnwindResult::kAborted;
218 }
219
220 if (regs->dex_pc() != 0) {
221 // Add a frame to represent the dex file.
222 EmitDexFrame(regs->dex_pc(), arch, stack);
223
224 // Clear the dex pc so that we don't repeat this frame later.
225 regs->set_dex_pc(0);
226 }
227
228 // Add the frame to |stack|. Must use GetModuleForAddress rather than
229 // GetExistingModuleForAddress because the unwound-to address may be in a
230 // module associated with a different unwinder.
231 const ModuleCache::Module* module =
232 module_cache()->GetModuleForAddress(regs->pc());
233 stack->emplace_back(regs->pc(), module);
234 } while (CanUnwindFrom(stack->back()));
235
236 // Restore registers necessary for further unwinding in |thread_context|.
237 CopyToRegisterContext(regs.get(), thread_context);
238 return UnwindResult::kUnrecognizedFrame;
239 }
240
241 std::unique_ptr<const ModuleCache::Module>
TryCreateModuleForAddress(uintptr_t address)242 NativeUnwinderAndroid::TryCreateModuleForAddress(uintptr_t address) {
243 unwindstack::MapInfo* map_info =
244 memory_regions_map_->maps()->Find(address).get();
245 if (map_info == nullptr || !(map_info->flags() & PROT_EXEC) ||
246 map_info->flags() & unwindstack::MAPS_FLAGS_DEVICE_MAP) {
247 return nullptr;
248 }
249 return std::make_unique<NonElfModule>(map_info);
250 }
251
GetOrCreateDexFiles(unwindstack::ArchEnum arch)252 unwindstack::DexFiles* NativeUnwinderAndroid::GetOrCreateDexFiles(
253 unwindstack::ArchEnum arch) {
254 if (!dex_files_) {
255 dex_files_ = unwindstack::CreateDexFiles(
256 arch, memory_regions_map_->memory(), search_libs_);
257 }
258 return dex_files_.get();
259 }
260
EmitDexFrame(uintptr_t dex_pc,unwindstack::ArchEnum arch,std::vector<Frame> * stack)261 void NativeUnwinderAndroid::EmitDexFrame(uintptr_t dex_pc,
262 unwindstack::ArchEnum arch,
263 std::vector<Frame>* stack) {
264 const ModuleCache::Module* module =
265 module_cache()->GetExistingModuleForAddress(dex_pc);
266 if (!module) {
267 // The region containing |dex_pc| may not be in module_cache() since it's
268 // usually not executable (.dex file). Since non-executable regions
269 // are used much less commonly, it's lazily added here instead of from
270 // AddInitialModulesFromMaps().
271 unwindstack::MapInfo* map_info =
272 memory_regions_map_->maps()->Find(dex_pc).get();
273 if (map_info) {
274 auto new_module = std::make_unique<NonElfModule>(map_info);
275 module = new_module.get();
276 module_cache()->AddCustomNativeModule(std::move(new_module));
277 }
278 }
279
280 stack->emplace_back(dex_pc, module);
281 }
282
283 } // namespace base
284