1 // Copyright 2019 The Chromium Authors. All rights reserved.
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 "third_party/libunwindstack/src/libunwindstack/include/unwindstack/Elf.h"
13 #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/Memory.h"
14 #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/Regs.h"
15
16 #include "base/memory/ptr_util.h"
17 #include "base/notreached.h"
18 #include "base/profiler/module_cache.h"
19 #include "base/profiler/native_unwinder.h"
20 #include "base/profiler/profile_builder.h"
21 #include "build/build_config.h"
22
23 #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
24 #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/MachineArm.h"
25 #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/RegsArm.h"
26 #elif defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_64_BITS)
27 #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/MachineArm64.h"
28 #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/RegsArm64.h"
29 #endif // #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
30
31 namespace base {
32 namespace {
33
34 class NonElfModule : public ModuleCache::Module {
35 public:
NonElfModule(unwindstack::MapInfo * map_info)36 NonElfModule(unwindstack::MapInfo* map_info)
37 : start_(map_info->start),
38 size_(map_info->end - start_),
39 map_info_name_(map_info->name) {}
40 ~NonElfModule() override = default;
41
GetBaseAddress() const42 uintptr_t GetBaseAddress() const override { return start_; }
43
GetId() const44 std::string GetId() const override { return std::string(); }
45
GetDebugBasename() const46 FilePath GetDebugBasename() const override {
47 return FilePath(map_info_name_);
48 }
49
50 // Gets the size of the module.
GetSize() const51 size_t GetSize() const override { return size_; }
52
53 // True if this is a native module.
IsNative() const54 bool IsNative() const override { return true; }
55
56 private:
57 const uintptr_t start_;
58 const size_t size_;
59 const std::string map_info_name_;
60 };
61
CreateFromRegisterContext(RegisterContext * thread_context)62 std::unique_ptr<unwindstack::Regs> CreateFromRegisterContext(
63 RegisterContext* thread_context) {
64 #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
65 return WrapUnique<unwindstack::Regs>(unwindstack::RegsArm::Read(
66 reinterpret_cast<void*>(&thread_context->arm_r0)));
67 #elif defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_64_BITS)
68 return WrapUnique<unwindstack::Regs>(unwindstack::RegsArm64::Read(
69 reinterpret_cast<void*>(&thread_context->regs[0])));
70 #else // #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
71 NOTREACHED();
72 return nullptr;
73 #endif // #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
74 }
75
CopyToRegisterContext(unwindstack::Regs * regs,RegisterContext * thread_context)76 void CopyToRegisterContext(unwindstack::Regs* regs,
77 RegisterContext* thread_context) {
78 #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
79 memcpy(reinterpret_cast<void*>(&thread_context->arm_r0), regs->RawData(),
80 unwindstack::ARM_REG_LAST * sizeof(uintptr_t));
81 #elif defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_64_BITS)
82 memcpy(reinterpret_cast<void*>(&thread_context->regs[0]), regs->RawData(),
83 unwindstack::ARM64_REG_LAST * sizeof(uintptr_t));
84 #else // #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
85 NOTREACHED();
86 #endif // #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
87 }
88
89 } // namespace
90
UnwindStackMemoryAndroid(uintptr_t stack_ptr,uintptr_t stack_top)91 UnwindStackMemoryAndroid::UnwindStackMemoryAndroid(uintptr_t stack_ptr,
92 uintptr_t stack_top)
93 : stack_ptr_(stack_ptr), stack_top_(stack_top) {
94 DCHECK_LE(stack_ptr_, stack_top_);
95 }
96
97 UnwindStackMemoryAndroid::~UnwindStackMemoryAndroid() = default;
98
Read(uint64_t addr,void * dst,size_t size)99 size_t UnwindStackMemoryAndroid::Read(uint64_t addr, void* dst, size_t size) {
100 if (addr < stack_ptr_)
101 return 0;
102 if (size >= stack_top_ || addr > stack_top_ - size)
103 return 0;
104 memcpy(dst, reinterpret_cast<void*>(addr), size);
105 return size;
106 }
107
108 // static
CreateMaps()109 std::unique_ptr<unwindstack::Maps> NativeUnwinderAndroid::CreateMaps() {
110 auto maps = std::make_unique<unwindstack::LocalMaps>();
111 if (maps->Parse())
112 return maps;
113 return nullptr;
114 }
115
116 // static
117 std::unique_ptr<unwindstack::Memory>
CreateProcessMemory()118 NativeUnwinderAndroid::CreateProcessMemory() {
119 return unwindstack::Memory::CreateLocalProcessMemory();
120 }
121
NativeUnwinderAndroid(unwindstack::Maps * memory_regions_map,unwindstack::Memory * process_memory,uintptr_t exclude_module_with_base_address)122 NativeUnwinderAndroid::NativeUnwinderAndroid(
123 unwindstack::Maps* memory_regions_map,
124 unwindstack::Memory* process_memory,
125 uintptr_t exclude_module_with_base_address)
126 : memory_regions_map_(memory_regions_map),
127 process_memory_(process_memory),
128 exclude_module_with_base_address_(exclude_module_with_base_address) {}
129
130 NativeUnwinderAndroid::~NativeUnwinderAndroid() = default;
131
AddInitialModules(ModuleCache * module_cache)132 void NativeUnwinderAndroid::AddInitialModules(ModuleCache* module_cache) {
133 AddInitialModulesFromMaps(*memory_regions_map_, module_cache);
134 }
135
CanUnwindFrom(const Frame & current_frame) const136 bool NativeUnwinderAndroid::CanUnwindFrom(const Frame& current_frame) const {
137 return current_frame.module && current_frame.module->IsNative() &&
138 current_frame.module->GetBaseAddress() !=
139 exclude_module_with_base_address_;
140 }
141
TryUnwind(RegisterContext * thread_context,uintptr_t stack_top,ModuleCache * module_cache,std::vector<Frame> * stack) const142 UnwindResult NativeUnwinderAndroid::TryUnwind(RegisterContext* thread_context,
143 uintptr_t stack_top,
144 ModuleCache* module_cache,
145 std::vector<Frame>* stack) const {
146 auto regs = CreateFromRegisterContext(thread_context);
147 DCHECK(regs);
148 unwindstack::ArchEnum arch = regs->Arch();
149
150 do {
151 uint64_t cur_pc = regs->pc();
152 uint64_t cur_sp = regs->sp();
153 unwindstack::MapInfo* map_info = memory_regions_map_->Find(cur_pc);
154 if (map_info == nullptr ||
155 map_info->flags & unwindstack::MAPS_FLAGS_DEVICE_MAP) {
156 break;
157 }
158
159 unwindstack::Elf* elf =
160 map_info->GetElf({process_memory_, [](unwindstack::Memory*) {}}, arch);
161 if (!elf->valid())
162 break;
163
164 UnwindStackMemoryAndroid stack_memory(cur_sp, stack_top);
165 uintptr_t rel_pc = elf->GetRelPc(cur_pc, map_info);
166 bool finished = false;
167 bool stepped =
168 elf->StepIfSignalHandler(rel_pc, regs.get(), &stack_memory) ||
169 elf->Step(rel_pc, regs.get(), &stack_memory, &finished);
170 if (stepped && finished)
171 return UnwindResult::COMPLETED;
172
173 if (!stepped) {
174 // Stepping failed. Try unwinding using return address.
175 if (stack->size() == 1) {
176 if (!regs->SetPcFromReturnAddress(&stack_memory))
177 return UnwindResult::ABORTED;
178 } else {
179 break;
180 }
181 }
182
183 // If the pc and sp didn't change, then consider everything stopped.
184 if (cur_pc == regs->pc() && cur_sp == regs->sp())
185 return UnwindResult::ABORTED;
186
187 // Exclusive range of expected stack pointer values after the unwind.
188 struct {
189 uintptr_t start;
190 uintptr_t end;
191 } expected_stack_pointer_range = {cur_sp, stack_top};
192 if (regs->sp() < expected_stack_pointer_range.start ||
193 regs->sp() >= expected_stack_pointer_range.end) {
194 return UnwindResult::ABORTED;
195 }
196
197 if (regs->dex_pc() != 0) {
198 // Add a frame to represent the dex file.
199 EmitDexFrame(regs->dex_pc(), module_cache, stack);
200
201 // Clear the dex pc so that we don't repeat this frame later.
202 regs->set_dex_pc(0);
203 }
204
205 // Add the frame to |stack|. Must use GetModuleForAddress rather than
206 // GetExistingModuleForAddress because the unwound-to address may be in a
207 // module associated with a different unwinder.
208 const ModuleCache::Module* module =
209 module_cache->GetModuleForAddress(regs->pc());
210 stack->emplace_back(regs->pc(), module);
211 } while (CanUnwindFrom(stack->back()));
212
213 // Restore registers necessary for further unwinding in |thread_context|.
214 CopyToRegisterContext(regs.get(), thread_context);
215 return UnwindResult::UNRECOGNIZED_FRAME;
216 }
217
218 // static
AddInitialModulesFromMaps(const unwindstack::Maps & memory_regions_map,ModuleCache * module_cache)219 void NativeUnwinderAndroid::AddInitialModulesFromMaps(
220 const unwindstack::Maps& memory_regions_map,
221 ModuleCache* module_cache) {
222 // The effect of this loop is to create modules for the executable regions in
223 // the memory map. Regions composing a mapped ELF file are handled specially
224 // however: for just one module extending from the ELF base address to the
225 // *last* executable region backed by the file is implicitly created by
226 // ModuleCache. This avoids duplicate module instances covering the same
227 // in-memory module in the case that a module has multiple mmapped executable
228 // regions.
229 for (const std::unique_ptr<unwindstack::MapInfo>& region :
230 memory_regions_map) {
231 if (!(region->flags & PROT_EXEC))
232 continue;
233
234 // Use the standard ModuleCache POSIX module representation for ELF files.
235 // This call returns the containing ELF module for the region, creating it
236 // if it doesn't exist.
237 if (module_cache->GetModuleForAddress(
238 static_cast<uintptr_t>(region->start))) {
239 continue;
240 }
241
242 // Non-ELF modules are represented with NonElfModule.
243 module_cache->AddCustomNativeModule(
244 std::make_unique<NonElfModule>(region.get()));
245 }
246 }
247
EmitDexFrame(uintptr_t dex_pc,ModuleCache * module_cache,std::vector<Frame> * stack) const248 void NativeUnwinderAndroid::EmitDexFrame(uintptr_t dex_pc,
249 ModuleCache* module_cache,
250 std::vector<Frame>* stack) const {
251 const ModuleCache::Module* module =
252 module_cache->GetExistingModuleForAddress(dex_pc);
253 if (!module) {
254 // The region containing |dex_pc| may not be in |module_cache| since it's
255 // usually not executable (.dex file). Since non-executable regions
256 // are used much less commonly, it's lazily added here instead of from
257 // AddInitialModulesFromMaps().
258 unwindstack::MapInfo* map_info = memory_regions_map_->Find(dex_pc);
259 if (map_info) {
260 auto new_module = std::make_unique<NonElfModule>(map_info);
261 module = new_module.get();
262 module_cache->AddCustomNativeModule(std::move(new_module));
263 }
264 }
265 stack->emplace_back(dex_pc, module);
266 }
267
268 } // namespace base
269