OSDN Git Service

Merge "ext4_utils: copy mke2fs.conf to /etc" into oc-dr1-dev am: 7f60c1a8af
[android-x86/system-extras.git] / simpleperf / dwarf_unwind.cpp
index d48a347..2e0a298 100644 (file)
@@ -94,10 +94,13 @@ static ucontext_t BuildUContextFromRegs(const RegSet& regs __attribute__((unused
   return ucontext;
 }
 
-std::vector<uint64_t> UnwindCallChain(ArchType arch, const ThreadEntry& thread,
+std::vector<uint64_t> UnwindCallChain(int abi, const ThreadEntry& thread,
                                       const RegSet& regs, const char* stack,
                                       size_t stack_size, bool strict_arch_check) {
   std::vector<uint64_t> result;
+  ArchType arch = (abi != PERF_SAMPLE_REGS_ABI_32) ?
+                      ScopedCurrentArch::GetCurrentArch() :
+                      ScopedCurrentArch::GetCurrentArch32();
   if (!IsArchTheSame(arch, GetBuildArch(), strict_arch_check)) {
     LOG(FATAL) << "simpleperf is built in arch " << GetArchString(GetBuildArch())
             << ", and can't do stack unwinding for arch " << GetArchString(arch);
@@ -110,9 +113,9 @@ std::vector<uint64_t> UnwindCallChain(ArchType arch, const ThreadEntry& thread,
   }
   uint64_t stack_addr = sp_reg_value;
 
-  std::vector<backtrace_map_t> bt_maps(thread.maps.size());
+  std::vector<backtrace_map_t> bt_maps(thread.maps->size());
   size_t map_index = 0;
-  for (auto& map : thread.maps) {
+  for (auto& map : *thread.maps) {
     backtrace_map_t& bt_map = bt_maps[map_index++];
     bt_map.start = map->start_addr;
     bt_map.end = map->start_addr + map->len;
@@ -131,6 +134,10 @@ std::vector<uint64_t> UnwindCallChain(ArchType arch, const ThreadEntry& thread,
   ucontext_t ucontext = BuildUContextFromRegs(regs);
   if (backtrace->Unwind(0, &ucontext)) {
     for (auto it = backtrace->begin(); it != backtrace->end(); ++it) {
+      // Unwinding in arm architecture can return 0 pc address.
+      if (it->pc == 0) {
+        break;
+      }
       result.push_back(it->pc);
     }
   }