native_unwinder_android.cc 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  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. #include "base/profiler/native_unwinder_android.h"
  5. #include <sys/mman.h>
  6. #include <string>
  7. #include <vector>
  8. #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/Elf.h"
  9. #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/Memory.h"
  10. #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/Regs.h"
  11. #include "base/memory/ptr_util.h"
  12. #include "base/notreached.h"
  13. #include "base/profiler/module_cache.h"
  14. #include "base/profiler/profile_builder.h"
  15. #include "build/build_config.h"
  16. #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
  17. #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/MachineArm.h"
  18. #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/RegsArm.h"
  19. #elif defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_64_BITS)
  20. #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/MachineArm64.h"
  21. #include "third_party/libunwindstack/src/libunwindstack/include/unwindstack/RegsArm64.h"
  22. #endif // #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
  23. namespace base {
  24. namespace {
  25. class NonElfModule : public ModuleCache::Module {
  26. public:
  27. NonElfModule(unwindstack::MapInfo* map_info)
  28. : start_(map_info->start),
  29. size_(map_info->end - start_),
  30. map_info_name_(map_info->name) {}
  31. ~NonElfModule() override = default;
  32. uintptr_t GetBaseAddress() const override { return start_; }
  33. std::string GetId() const override { return std::string(); }
  34. FilePath GetDebugBasename() const override {
  35. return FilePath(map_info_name_);
  36. }
  37. // Gets the size of the module.
  38. size_t GetSize() const override { return size_; }
  39. // True if this is a native module.
  40. bool IsNative() const override { return true; }
  41. private:
  42. const uintptr_t start_;
  43. const size_t size_;
  44. const std::string map_info_name_;
  45. };
  46. std::unique_ptr<unwindstack::Regs> CreateFromRegisterContext(
  47. RegisterContext* thread_context) {
  48. #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
  49. return WrapUnique<unwindstack::Regs>(unwindstack::RegsArm::Read(
  50. reinterpret_cast<void*>(&thread_context->arm_r0)));
  51. #elif defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_64_BITS)
  52. return WrapUnique<unwindstack::Regs>(unwindstack::RegsArm64::Read(
  53. reinterpret_cast<void*>(&thread_context->regs[0])));
  54. #else // #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
  55. NOTREACHED();
  56. return nullptr;
  57. #endif // #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
  58. }
  59. void CopyToRegisterContext(unwindstack::Regs* regs,
  60. RegisterContext* thread_context) {
  61. #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
  62. memcpy(reinterpret_cast<void*>(&thread_context->arm_r0), regs->RawData(),
  63. unwindstack::ARM_REG_LAST * sizeof(uintptr_t));
  64. #elif defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_64_BITS)
  65. memcpy(reinterpret_cast<void*>(&thread_context->regs[0]), regs->RawData(),
  66. unwindstack::ARM64_REG_LAST * sizeof(uintptr_t));
  67. #else // #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
  68. NOTREACHED();
  69. #endif // #if defined(ARCH_CPU_ARM_FAMILY) && defined(ARCH_CPU_32_BITS)
  70. }
  71. } // namespace
  72. UnwindStackMemoryAndroid::UnwindStackMemoryAndroid(uintptr_t stack_ptr,
  73. uintptr_t stack_top)
  74. : stack_ptr_(stack_ptr), stack_top_(stack_top) {
  75. DCHECK_LE(stack_ptr_, stack_top_);
  76. }
  77. UnwindStackMemoryAndroid::~UnwindStackMemoryAndroid() = default;
  78. size_t UnwindStackMemoryAndroid::Read(uint64_t addr, void* dst, size_t size) {
  79. if (addr < stack_ptr_)
  80. return 0;
  81. if (size >= stack_top_ || addr > stack_top_ - size)
  82. return 0;
  83. memcpy(dst, reinterpret_cast<void*>(addr), size);
  84. return size;
  85. }
  86. // static
  87. std::unique_ptr<unwindstack::Maps> NativeUnwinderAndroid::CreateMaps() {
  88. auto maps = std::make_unique<unwindstack::LocalMaps>();
  89. if (maps->Parse())
  90. return maps;
  91. return nullptr;
  92. }
  93. // static
  94. std::unique_ptr<unwindstack::Memory>
  95. NativeUnwinderAndroid::CreateProcessMemory() {
  96. return unwindstack::Memory::CreateLocalProcessMemory();
  97. }
  98. NativeUnwinderAndroid::NativeUnwinderAndroid(
  99. unwindstack::Maps* memory_regions_map,
  100. unwindstack::Memory* process_memory,
  101. uintptr_t exclude_module_with_base_address)
  102. : memory_regions_map_(memory_regions_map),
  103. process_memory_(process_memory),
  104. exclude_module_with_base_address_(exclude_module_with_base_address) {}
  105. NativeUnwinderAndroid::~NativeUnwinderAndroid() {
  106. if (module_cache())
  107. module_cache()->UnregisterAuxiliaryModuleProvider(this);
  108. }
  109. void NativeUnwinderAndroid::InitializeModules() {
  110. module_cache()->RegisterAuxiliaryModuleProvider(this);
  111. }
  112. bool NativeUnwinderAndroid::CanUnwindFrom(const Frame& current_frame) const {
  113. return current_frame.module && current_frame.module->IsNative() &&
  114. current_frame.module->GetBaseAddress() !=
  115. exclude_module_with_base_address_;
  116. }
  117. UnwindResult NativeUnwinderAndroid::TryUnwind(RegisterContext* thread_context,
  118. uintptr_t stack_top,
  119. std::vector<Frame>* stack) const {
  120. auto regs = CreateFromRegisterContext(thread_context);
  121. DCHECK(regs);
  122. unwindstack::ArchEnum arch = regs->Arch();
  123. do {
  124. uint64_t cur_pc = regs->pc();
  125. uint64_t cur_sp = regs->sp();
  126. unwindstack::MapInfo* map_info = memory_regions_map_->Find(cur_pc);
  127. if (map_info == nullptr ||
  128. map_info->flags & unwindstack::MAPS_FLAGS_DEVICE_MAP) {
  129. break;
  130. }
  131. unwindstack::Elf* elf = map_info->GetElf(
  132. {process_memory_.get(), [](unwindstack::Memory*) {}}, arch);
  133. if (!elf->valid())
  134. break;
  135. UnwindStackMemoryAndroid stack_memory(cur_sp, stack_top);
  136. uintptr_t rel_pc = elf->GetRelPc(cur_pc, map_info);
  137. bool finished = false;
  138. bool stepped =
  139. elf->StepIfSignalHandler(rel_pc, regs.get(), &stack_memory) ||
  140. elf->Step(rel_pc, regs.get(), &stack_memory, &finished);
  141. if (stepped && finished)
  142. return UnwindResult::kCompleted;
  143. if (!stepped) {
  144. // Stepping failed. Try unwinding using return address.
  145. if (stack->size() == 1) {
  146. if (!regs->SetPcFromReturnAddress(&stack_memory))
  147. return UnwindResult::kAborted;
  148. } else {
  149. break;
  150. }
  151. }
  152. // If the pc and sp didn't change, then consider everything stopped.
  153. if (cur_pc == regs->pc() && cur_sp == regs->sp())
  154. return UnwindResult::kAborted;
  155. // Exclusive range of expected stack pointer values after the unwind.
  156. struct {
  157. uintptr_t start;
  158. uintptr_t end;
  159. } expected_stack_pointer_range = {static_cast<uintptr_t>(cur_sp),
  160. stack_top};
  161. if (regs->sp() < expected_stack_pointer_range.start ||
  162. regs->sp() >= expected_stack_pointer_range.end) {
  163. return UnwindResult::kAborted;
  164. }
  165. if (regs->dex_pc() != 0) {
  166. // Add a frame to represent the dex file.
  167. EmitDexFrame(regs->dex_pc(), stack);
  168. // Clear the dex pc so that we don't repeat this frame later.
  169. regs->set_dex_pc(0);
  170. }
  171. // Add the frame to |stack|. Must use GetModuleForAddress rather than
  172. // GetExistingModuleForAddress because the unwound-to address may be in a
  173. // module associated with a different unwinder.
  174. const ModuleCache::Module* module =
  175. module_cache()->GetModuleForAddress(regs->pc());
  176. stack->emplace_back(regs->pc(), module);
  177. } while (CanUnwindFrom(stack->back()));
  178. // Restore registers necessary for further unwinding in |thread_context|.
  179. CopyToRegisterContext(regs.get(), thread_context);
  180. return UnwindResult::kUnrecognizedFrame;
  181. }
  182. std::unique_ptr<const ModuleCache::Module>
  183. NativeUnwinderAndroid::TryCreateModuleForAddress(uintptr_t address) {
  184. unwindstack::MapInfo* map_info = memory_regions_map_->Find(address);
  185. if (map_info == nullptr || !(map_info->flags & PROT_EXEC) ||
  186. map_info->flags & unwindstack::MAPS_FLAGS_DEVICE_MAP) {
  187. return nullptr;
  188. }
  189. return std::make_unique<NonElfModule>(map_info);
  190. }
  191. void NativeUnwinderAndroid::EmitDexFrame(uintptr_t dex_pc,
  192. std::vector<Frame>* stack) const {
  193. const ModuleCache::Module* module =
  194. module_cache()->GetExistingModuleForAddress(dex_pc);
  195. if (!module) {
  196. // The region containing |dex_pc| may not be in module_cache() since it's
  197. // usually not executable (.dex file). Since non-executable regions
  198. // are used much less commonly, it's lazily added here instead of from
  199. // AddInitialModulesFromMaps().
  200. unwindstack::MapInfo* map_info = memory_regions_map_->Find(dex_pc);
  201. if (map_info) {
  202. auto new_module = std::make_unique<NonElfModule>(map_info);
  203. module = new_module.get();
  204. module_cache()->AddCustomNativeModule(std::move(new_module));
  205. }
  206. }
  207. stack->emplace_back(dex_pc, module);
  208. }
  209. } // namespace base