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.
5 #include "base/profiler/native_unwinder_android.h"
12 #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/Elf.h"
13 #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/Maps.h"
14 #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/Memory.h"
15 #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/Regs.h"
17 #include "base/memory/ptr_util.h"
18 #include "base/metrics/metrics_hashes.h"
19 #include "base/notreached.h"
20 #include "base/profiler/module_cache.h"
21 #include "base/profiler/native_unwinder_android_map_delegate.h"
22 #include "base/profiler/native_unwinder_android_memory_regions_map_impl.h"
23 #include "base/profiler/profile_builder.h"
24 #include "build/build_config.h"
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)
37 class NonElfModule : public ModuleCache::Module {
39 explicit NonElfModule(unwindstack::MapInfo* map_info,
40 bool is_java_name_hashing_enabled)
41 : start_(map_info->start()),
42 size_(map_info->end() - start_),
43 map_info_name_(map_info->name()),
44 is_java_name_hashing_enabled_(is_java_name_hashing_enabled) {}
45 ~NonElfModule() override = default;
47 uintptr_t GetBaseAddress() const override { return start_; }
49 std::string GetId() const override {
50 // We provide a non-empty string only if Java name hashing is enabled, to
51 // allow us to easily filter out the results from outside the experiment.
52 if (is_java_name_hashing_enabled_) {
53 // Synthetic build id to use for DEX files that provide hashed function
54 // names rather than instruction pointers.
55 return "44444444BC18564712E780518FB3032B999";
61 FilePath GetDebugBasename() const override {
62 return FilePath(map_info_name_);
65 // Gets the size of the module.
66 size_t GetSize() const override { return size_; }
68 // True if this is a native module.
69 bool IsNative() const override { return true; }
72 const uintptr_t start_;
74 const std::string map_info_name_;
75 const bool is_java_name_hashing_enabled_;
78 std::unique_ptr<unwindstack::Regs> CreateFromRegisterContext(
79 RegisterContext* thread_context) {
80 #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
81 return WrapUnique<unwindstack::Regs>(unwindstack::RegsArm::Read(
82 reinterpret_cast<void*>(&thread_context->arm_r0)));
83 #elif defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_64_BITS)
84 return WrapUnique<unwindstack::Regs>(unwindstack::RegsArm64::Read(
85 reinterpret_cast<void*>(&thread_context->regs[0])));
86 #else // #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
89 #endif // #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
92 void CopyToRegisterContext(unwindstack::Regs* regs,
93 RegisterContext* thread_context) {
94 #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
95 memcpy(reinterpret_cast<void*>(&thread_context->arm_r0), regs->RawData(),
96 unwindstack::ARM_REG_LAST * sizeof(uintptr_t));
97 #elif defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_64_BITS)
98 memcpy(reinterpret_cast<void*>(&thread_context->regs[0]), regs->RawData(),
99 unwindstack::ARM64_REG_LAST * sizeof(uintptr_t));
100 #else // #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
102 #endif // #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
107 UnwindStackMemoryAndroid::UnwindStackMemoryAndroid(uintptr_t stack_ptr,
109 : stack_ptr_(stack_ptr), stack_top_(stack_top) {
110 DCHECK_LE(stack_ptr_, stack_top_);
113 UnwindStackMemoryAndroid::~UnwindStackMemoryAndroid() = default;
115 size_t UnwindStackMemoryAndroid::Read(uint64_t addr, void* dst, size_t size) {
116 if (addr < stack_ptr_)
118 if (size >= stack_top_ || addr > stack_top_ - size)
120 memcpy(dst, reinterpret_cast<void*>(addr), size);
125 std::unique_ptr<NativeUnwinderAndroidMemoryRegionsMap>
126 NativeUnwinderAndroid::CreateMemoryRegionsMap(bool use_updatable_maps) {
127 std::unique_ptr<unwindstack::Maps> maps;
128 if (use_updatable_maps) {
129 maps = std::make_unique<unwindstack::LocalUpdatableMaps>();
131 maps = std::make_unique<unwindstack::LocalMaps>();
133 const bool success = maps->Parse();
136 return std::make_unique<NativeUnwinderAndroidMemoryRegionsMapImpl>(
137 std::move(maps), unwindstack::Memory::CreateLocalProcessMemory());
140 NativeUnwinderAndroid::NativeUnwinderAndroid(
141 uintptr_t exclude_module_with_base_address,
142 NativeUnwinderAndroidMapDelegate* map_delegate,
143 bool is_java_name_hashing_enabled)
144 : is_java_name_hashing_enabled_(is_java_name_hashing_enabled),
145 exclude_module_with_base_address_(exclude_module_with_base_address),
146 map_delegate_(map_delegate),
148 static_cast<NativeUnwinderAndroidMemoryRegionsMapImpl*>(
149 map_delegate->GetMapReference())) {
150 DCHECK(map_delegate_);
151 DCHECK(memory_regions_map_);
154 NativeUnwinderAndroid::~NativeUnwinderAndroid() {
156 module_cache()->UnregisterAuxiliaryModuleProvider(this);
158 map_delegate_->ReleaseMapReference();
161 void NativeUnwinderAndroid::InitializeModules() {
162 module_cache()->RegisterAuxiliaryModuleProvider(this);
165 bool NativeUnwinderAndroid::CanUnwindFrom(const Frame& current_frame) const {
166 return current_frame.module && current_frame.module->IsNative() &&
167 current_frame.module->GetBaseAddress() !=
168 exclude_module_with_base_address_;
171 UnwindResult NativeUnwinderAndroid::TryUnwind(RegisterContext* thread_context,
173 std::vector<Frame>* stack) {
174 auto regs = CreateFromRegisterContext(thread_context);
176 unwindstack::ArchEnum arch = regs->Arch();
179 uint64_t cur_pc = regs->pc();
180 uint64_t cur_sp = regs->sp();
181 unwindstack::MapInfo* map_info =
182 memory_regions_map_->maps()->Find(cur_pc).get();
183 if (map_info == nullptr ||
184 map_info->flags() & unwindstack::MAPS_FLAGS_DEVICE_MAP) {
188 unwindstack::Elf* elf =
189 map_info->GetElf(memory_regions_map_->memory(), arch);
193 UnwindStackMemoryAndroid stack_memory(cur_sp, stack_top);
194 uintptr_t rel_pc = elf->GetRelPc(cur_pc, map_info);
195 bool is_signal_frame = false;
196 bool finished = false;
198 elf->StepIfSignalHandler(rel_pc, regs.get(), &stack_memory) ||
199 elf->Step(rel_pc, regs.get(), &stack_memory, &finished,
201 if (stepped && finished)
202 return UnwindResult::kCompleted;
205 // Stepping failed. Try unwinding using return address.
206 if (stack->size() == 1) {
207 if (!regs->SetPcFromReturnAddress(&stack_memory))
208 return UnwindResult::kAborted;
214 // If the pc and sp didn't change, then consider everything stopped.
215 if (cur_pc == regs->pc() && cur_sp == regs->sp())
216 return UnwindResult::kAborted;
218 // Exclusive range of expected stack pointer values after the unwind.
222 } expected_stack_pointer_range = {static_cast<uintptr_t>(cur_sp),
224 if (regs->sp() < expected_stack_pointer_range.start ||
225 regs->sp() >= expected_stack_pointer_range.end) {
226 return UnwindResult::kAborted;
229 if (regs->dex_pc() != 0) {
230 // Add a frame to represent the dex file.
231 EmitDexFrame(regs->dex_pc(), arch, stack);
233 // Clear the dex pc so that we don't repeat this frame later.
237 // Add the frame to |stack|. Must use GetModuleForAddress rather than
238 // GetExistingModuleForAddress because the unwound-to address may be in a
239 // module associated with a different unwinder.
240 const ModuleCache::Module* module =
241 module_cache()->GetModuleForAddress(regs->pc());
242 stack->emplace_back(regs->pc(), module);
243 } while (CanUnwindFrom(stack->back()));
245 // Restore registers necessary for further unwinding in |thread_context|.
246 CopyToRegisterContext(regs.get(), thread_context);
247 return UnwindResult::kUnrecognizedFrame;
250 std::unique_ptr<const ModuleCache::Module>
251 NativeUnwinderAndroid::TryCreateModuleForAddress(uintptr_t address) {
252 unwindstack::MapInfo* map_info =
253 memory_regions_map_->maps()->Find(address).get();
254 if (map_info == nullptr || !(map_info->flags() & PROT_EXEC) ||
255 map_info->flags() & unwindstack::MAPS_FLAGS_DEVICE_MAP) {
258 return std::make_unique<NonElfModule>(map_info,
259 is_java_name_hashing_enabled_);
262 unwindstack::DexFiles* NativeUnwinderAndroid::GetOrCreateDexFiles(
263 unwindstack::ArchEnum arch) {
265 dex_files_ = unwindstack::CreateDexFiles(
266 arch, memory_regions_map_->memory(), search_libs_);
268 return dex_files_.get();
271 void NativeUnwinderAndroid::EmitDexFrame(uintptr_t dex_pc,
272 unwindstack::ArchEnum arch,
273 std::vector<Frame>* stack) {
274 const ModuleCache::Module* module =
275 module_cache()->GetExistingModuleForAddress(dex_pc);
277 // The region containing |dex_pc| may not be in module_cache() since it's
278 // usually not executable (.dex file). Since non-executable regions
279 // are used much less commonly, it's lazily added here instead of from
280 // AddInitialModulesFromMaps().
281 unwindstack::MapInfo* map_info =
282 memory_regions_map_->maps()->Find(dex_pc).get();
284 auto new_module = std::make_unique<NonElfModule>(
285 map_info, is_java_name_hashing_enabled_);
286 module = new_module.get();
287 module_cache()->AddCustomNativeModule(std::move(new_module));
291 if (is_java_name_hashing_enabled_) {
292 unwindstack::SharedString function_name;
293 uint64_t function_offset = 0;
294 GetOrCreateDexFiles(arch)->GetFunctionName(
295 memory_regions_map_->maps(), dex_pc, &function_name, &function_offset);
297 HashMetricNameAs32Bits(static_cast<const std::string&>(function_name)),
301 stack->emplace_back(dex_pc, module);