summaryrefslogtreecommitdiff
path: root/simpleperf/OfflineUnwinder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'simpleperf/OfflineUnwinder.cpp')
-rw-r--r--simpleperf/OfflineUnwinder.cpp72
1 files changed, 22 insertions, 50 deletions
diff --git a/simpleperf/OfflineUnwinder.cpp b/simpleperf/OfflineUnwinder.cpp
index 07eda11f..b6b7d91f 100644
--- a/simpleperf/OfflineUnwinder.cpp
+++ b/simpleperf/OfflineUnwinder.cpp
@@ -18,8 +18,6 @@
#include <sys/mman.h>
-#include <unordered_map>
-
#include <android-base/logging.h>
#include <unwindstack/MachineArm.h>
#include <unwindstack/MachineArm64.h>
@@ -121,29 +119,22 @@ static unwindstack::Regs* GetBacktraceRegs(const RegSet& regs) {
static unwindstack::MapInfo* CreateMapInfo(const MapEntry* entry) {
const char* name = entry->dso->GetDebugFilePath().c_str();
uint64_t pgoff = entry->pgoff;
- auto tuple = SplitUrlInApk(entry->dso->GetDebugFilePath());
- if (std::get<0>(tuple)) {
- // The unwinder does not understand the ! format, so change back to
- // the previous format (apk, offset).
- EmbeddedElf* elf = ApkInspector::FindElfInApkByName(std::get<1>(tuple), std::get<2>(tuple));
- if (elf != nullptr) {
- name = elf->filepath().c_str();
- pgoff += elf->entry_offset();
+ if (entry->pgoff == 0) {
+ auto tuple = SplitUrlInApk(entry->dso->GetDebugFilePath());
+ if (std::get<0>(tuple)) {
+ // The unwinder does not understand the ! format, so change back to
+ // the previous format (apk, offset).
+ EmbeddedElf* elf = ApkInspector::FindElfInApkByName(std::get<1>(tuple), std::get<2>(tuple));
+ if (elf != nullptr) {
+ name = elf->filepath().c_str();
+ pgoff = elf->entry_offset();
+ }
}
}
return new unwindstack::MapInfo(nullptr, entry->start_addr, entry->get_end_addr(), pgoff,
- PROT_READ | entry->flags, name);
+ PROT_READ | PROT_EXEC | entry->flags, name);
}
-class UnwindMaps : public unwindstack::Maps {
- public:
- void UpdateMaps(const MapSet& map_set);
-
- private:
- uint64_t version_ = 0u;
- std::vector<const MapEntry*> entries_;
-};
-
void UnwindMaps::UpdateMaps(const MapSet& map_set) {
if (version_ == map_set.version) {
return;
@@ -186,31 +177,15 @@ void UnwindMaps::UpdateMaps(const MapSet& map_set) {
});
entries_.resize(map_set.maps.size());
maps_.resize(map_set.maps.size());
- // prev_map is needed by libunwindstack to find the start of an embedded lib in an apk.
- // See http://b/120981155.
- for (size_t i = 1; i < maps_.size(); ++i) {
- maps_[i]->prev_map = maps_[i-1].get();
- }
}
-class OfflineUnwinderImpl : public OfflineUnwinder {
- public:
- OfflineUnwinderImpl(bool collect_stat) : collect_stat_(collect_stat) {
- unwindstack::Elf::SetCachingEnabled(true);
- }
-
- bool UnwindCallChain(const ThreadEntry& thread, const RegSet& regs, const char* stack,
- size_t stack_size, std::vector<uint64_t>* ips,
- std::vector<uint64_t>* sps) override;
-
- private:
- bool collect_stat_;
- std::unordered_map<pid_t, UnwindMaps> cached_maps_;
-};
+OfflineUnwinder::OfflineUnwinder(bool collect_stat) : collect_stat_(collect_stat) {
+ unwindstack::Elf::SetCachingEnabled(true);
+}
-bool OfflineUnwinderImpl::UnwindCallChain(const ThreadEntry& thread, const RegSet& regs,
- const char* stack, size_t stack_size,
- std::vector<uint64_t>* ips, std::vector<uint64_t>* sps) {
+bool OfflineUnwinder::UnwindCallChain(const ThreadEntry& thread, const RegSet& regs,
+ const char* stack, size_t stack_size,
+ std::vector<uint64_t>* ips, std::vector<uint64_t>* sps) {
uint64_t start_time;
if (collect_stat_) {
start_time = GetSystemClock();
@@ -228,14 +203,15 @@ bool OfflineUnwinderImpl::UnwindCallChain(const ThreadEntry& thread, const RegSe
UnwindMaps& cached_map = cached_maps_[thread.pid];
cached_map.UpdateMaps(*thread.maps);
+ std::shared_ptr<unwindstack::MemoryOfflineBuffer> stack_memory(
+ new unwindstack::MemoryOfflineBuffer(reinterpret_cast<const uint8_t*>(stack),
+ stack_addr, stack_addr + stack_size));
std::unique_ptr<unwindstack::Regs> unwind_regs(GetBacktraceRegs(regs));
if (!unwind_regs) {
return false;
}
- unwindstack::Unwinder unwinder(
- MAX_UNWINDING_FRAMES, &cached_map, unwind_regs.get(),
- unwindstack::Memory::CreateOfflineMemory(reinterpret_cast<const uint8_t*>(stack), stack_addr,
- stack_addr + stack_size));
+ unwindstack::Unwinder unwinder(MAX_UNWINDING_FRAMES, &cached_map, unwind_regs.get(),
+ stack_memory);
unwinder.SetResolveNames(false);
unwinder.Unwind();
size_t last_jit_method_frame = UINT_MAX;
@@ -307,8 +283,4 @@ bool OfflineUnwinderImpl::UnwindCallChain(const ThreadEntry& thread, const RegSe
return true;
}
-std::unique_ptr<OfflineUnwinder> OfflineUnwinder::Create(bool collect_stat) {
- return std::unique_ptr<OfflineUnwinder>(new OfflineUnwinderImpl(collect_stat));
-}
-
} // namespace simpleperf