UnwindStackMap.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /*
  2. * Copyright (C) 2017 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <stdint.h>
  17. #include <stdlib.h>
  18. #include <sys/types.h>
  19. #include <string>
  20. #include <vector>
  21. #include <backtrace/BacktraceMap.h>
  22. #include <unwindstack/Elf.h>
  23. #include <unwindstack/MapInfo.h>
  24. #include <unwindstack/Maps.h>
  25. #include <unwindstack/Regs.h>
  26. #include "UnwindStackMap.h"
  27. //-------------------------------------------------------------------------
  28. UnwindStackMap::UnwindStackMap(pid_t pid) : BacktraceMap(pid) {}
  29. bool UnwindStackMap::Build() {
  30. if (pid_ == 0) {
  31. pid_ = getpid();
  32. stack_maps_.reset(new unwindstack::LocalMaps);
  33. } else {
  34. stack_maps_.reset(new unwindstack::RemoteMaps(pid_));
  35. }
  36. // Create the process memory object.
  37. process_memory_ = unwindstack::Memory::CreateProcessMemory(pid_);
  38. // Create a JitDebug object for getting jit unwind information.
  39. std::vector<std::string> search_libs_{"libart.so", "libartd.so"};
  40. jit_debug_.reset(new unwindstack::JitDebug(process_memory_, search_libs_));
  41. #if !defined(NO_LIBDEXFILE_SUPPORT)
  42. dex_files_.reset(new unwindstack::DexFiles(process_memory_, search_libs_));
  43. #endif
  44. if (!stack_maps_->Parse()) {
  45. return false;
  46. }
  47. // Iterate through the maps and fill in the backtrace_map_t structure.
  48. for (const auto& map_info : *stack_maps_) {
  49. backtrace_map_t map;
  50. map.start = map_info->start;
  51. map.end = map_info->end;
  52. map.offset = map_info->offset;
  53. // Set to -1 so that it is demand loaded.
  54. map.load_bias = static_cast<uint64_t>(-1);
  55. map.flags = map_info->flags;
  56. map.name = map_info->name;
  57. maps_.push_back(map);
  58. }
  59. return true;
  60. }
  61. void UnwindStackMap::FillIn(uint64_t addr, backtrace_map_t* map) {
  62. BacktraceMap::FillIn(addr, map);
  63. if (map->load_bias != static_cast<uint64_t>(-1)) {
  64. return;
  65. }
  66. // Fill in the load_bias.
  67. unwindstack::MapInfo* map_info = stack_maps_->Find(addr);
  68. if (map_info == nullptr) {
  69. return;
  70. }
  71. map->load_bias = map_info->GetLoadBias(process_memory_);
  72. }
  73. uint64_t UnwindStackMap::GetLoadBias(size_t index) {
  74. if (index >= stack_maps_->Total()) {
  75. return 0;
  76. }
  77. unwindstack::MapInfo* map_info = stack_maps_->Get(index);
  78. if (map_info == nullptr) {
  79. return 0;
  80. }
  81. return map_info->GetLoadBias(process_memory_);
  82. }
  83. std::string UnwindStackMap::GetFunctionName(uint64_t pc, uint64_t* offset) {
  84. *offset = 0;
  85. unwindstack::Maps* maps = stack_maps();
  86. // Get the map for this
  87. unwindstack::MapInfo* map_info = maps->Find(pc);
  88. if (map_info == nullptr || map_info->flags & PROT_DEVICE_MAP) {
  89. return "";
  90. }
  91. if (arch_ == unwindstack::ARCH_UNKNOWN) {
  92. if (pid_ == getpid()) {
  93. arch_ = unwindstack::Regs::CurrentArch();
  94. } else {
  95. // Create a remote regs, to figure out the architecture.
  96. std::unique_ptr<unwindstack::Regs> regs(unwindstack::Regs::RemoteGet(pid_));
  97. arch_ = regs->Arch();
  98. }
  99. }
  100. unwindstack::Elf* elf = map_info->GetElf(process_memory(), arch_);
  101. std::string name;
  102. uint64_t func_offset;
  103. if (!elf->GetFunctionName(elf->GetRelPc(pc, map_info), &name, &func_offset)) {
  104. return "";
  105. }
  106. *offset = func_offset;
  107. return name;
  108. }
  109. std::shared_ptr<unwindstack::Memory> UnwindStackMap::GetProcessMemory() {
  110. return process_memory_;
  111. }
  112. UnwindStackOfflineMap::UnwindStackOfflineMap(pid_t pid) : UnwindStackMap(pid) {}
  113. bool UnwindStackOfflineMap::Build() {
  114. return false;
  115. }
  116. bool UnwindStackOfflineMap::Build(const std::vector<backtrace_map_t>& backtrace_maps) {
  117. for (const backtrace_map_t& map : backtrace_maps) {
  118. maps_.push_back(map);
  119. }
  120. std::sort(maps_.begin(), maps_.end(),
  121. [](const backtrace_map_t& a, const backtrace_map_t& b) { return a.start < b.start; });
  122. unwindstack::Maps* maps = new unwindstack::Maps;
  123. stack_maps_.reset(maps);
  124. for (const backtrace_map_t& map : maps_) {
  125. maps->Add(map.start, map.end, map.offset, map.flags, map.name, map.load_bias);
  126. }
  127. return true;
  128. }
  129. bool UnwindStackOfflineMap::CreateProcessMemory(const backtrace_stackinfo_t& stack) {
  130. if (stack.start >= stack.end) {
  131. return false;
  132. }
  133. // Create the process memory from the stack data.
  134. if (memory_ == nullptr) {
  135. memory_ = new unwindstack::MemoryOfflineBuffer(stack.data, stack.start, stack.end);
  136. process_memory_.reset(memory_);
  137. } else {
  138. memory_->Reset(stack.data, stack.start, stack.end);
  139. }
  140. return true;
  141. }
  142. //-------------------------------------------------------------------------
  143. // BacktraceMap create function.
  144. //-------------------------------------------------------------------------
  145. BacktraceMap* BacktraceMap::Create(pid_t pid, bool uncached) {
  146. BacktraceMap* map;
  147. if (uncached) {
  148. // Force use of the base class to parse the maps when this call is made.
  149. map = new BacktraceMap(pid);
  150. } else if (pid == getpid()) {
  151. map = new UnwindStackMap(0);
  152. } else {
  153. map = new UnwindStackMap(pid);
  154. }
  155. if (!map->Build()) {
  156. delete map;
  157. return nullptr;
  158. }
  159. return map;
  160. }
  161. //-------------------------------------------------------------------------
  162. // BacktraceMap create offline function.
  163. //-------------------------------------------------------------------------
  164. BacktraceMap* BacktraceMap::CreateOffline(pid_t pid, const std::vector<backtrace_map_t>& maps) {
  165. UnwindStackOfflineMap* map = new UnwindStackOfflineMap(pid);
  166. if (!map->Build(maps)) {
  167. delete map;
  168. return nullptr;
  169. }
  170. return map;
  171. }