diff --git a/include/virtual_runtime.h b/include/virtual_runtime.h index 07bcb36e489a7fc020e79d1bc26b08cb79fbf27f..ab3875001090f491caef20b7d2084c13f769d9c8 100644 --- a/include/virtual_runtime.h +++ b/include/virtual_runtime.h @@ -55,6 +55,7 @@ public: using CollectSymbolCallBack = std::function; void SetRecordMode(RecordCallBack recordCallBack); + void SetCallStackDwarf(bool isCallStackDwarf); void SetCollectSymbolCallBack(CollectSymbolCallBack collectSymbolCallBack); // this both used in report and record follow @@ -166,6 +167,7 @@ public: const bool loadSymboleWhenNeeded_ = true; // this is a feature config private: + bool isCallStackDwarf_ = false; bool needkernelCallChain_ = false; bool disableUnwind_ = true; bool enableDebugInfoSymbolic_ = false; diff --git a/include/virtual_thread.h b/include/virtual_thread.h index 89f16a5d8b5950afdffeb51707fbe388ba3c13c4..938f7a7316899859c37a7fb0872f6af996907343 100644 --- a/include/virtual_thread.h +++ b/include/virtual_thread.h @@ -84,7 +84,7 @@ public: uint64_t len, uint64_t offset, uint32_t prot = 0); std::shared_ptr FindMapByAddr(uint64_t addr) const; std::shared_ptr FindMapByFileInfo(const std::string name, uint64_t offset) const; - int64_t FindMapIndexByAddr(uint64_t addr) const; + int64_t FindMapIndexByAddr(uint64_t addr, bool onDwarfSymbolizing = false) const; SymbolsFile *FindSymbolsFileByMap(std::shared_ptr map) const; bool ReadRoMemory(uint64_t vaddr, uint8_t *data, size_t size) const; #ifdef HIPERF_DEBUG @@ -101,6 +101,7 @@ private: bool IsSorted() const; #endif const std::vector> &symbolsFiles_; + mutable std::map OverlapPcMaps = {}; // proc/xx/map // use to put the parent thread's map diff --git a/src/subcommand_record.cpp b/src/subcommand_record.cpp index f147db6918cea06d1dfa827486242a0d1dca0b66..f9bc2e10aaafe45133582dc0c5f85444fc251c0b 100644 --- a/src/subcommand_record.cpp +++ b/src/subcommand_record.cpp @@ -902,6 +902,7 @@ bool SubCommandRecord::ParseCallStackOption(const std::vector &call } } isCallStackDwarf_ = true; + virtualRuntime_.SetCallStackDwarf(isCallStackDwarf_); SymbolsFile::needParseJsFunc_ = true; // only in record and dwarf mode need to parse } else { printf("Invalid -s value '%s'.\n", callStackType.at(0).c_str()); diff --git a/src/virtual_runtime.cpp b/src/virtual_runtime.cpp index d21128882a04104923712723c753c505a544a977..1e0572ff2c83413c0272e15498ace2e252cceaab 100644 --- a/src/virtual_runtime.cpp +++ b/src/virtual_runtime.cpp @@ -910,6 +910,11 @@ void VirtualRuntime::SetRecordMode(RecordCallBack recordCallBack) recordCallBack_ = recordCallBack; } +void VirtualRuntime::SetCallStackDwarf(bool isCallStackDwarf) +{ + isCallStackDwarf_ = isCallStackDwarf; +} + void VirtualRuntime::UpdateSymbols(std::shared_ptr map, pid_t pid) { CHECK_TRUE(map != nullptr && map->symbolFileIndex == -1, NO_RETVAL, 0, ""); @@ -1016,7 +1021,7 @@ const DfxSymbol VirtualRuntime::GetKernelSymbol(uint64_t ip, const std::vector= 1 ? memMapsIndexs_.size() - 1 : 0]]->end <= addr) { return illegal; } - constexpr int divisorNum {2}; - std::size_t left {0}; - std::size_t right {memMapsIndexs_.size()}; - std::size_t mid = (right - left) / divisorNum + left; - while (left < right) { - if (addr < memMaps_[memMapsIndexs_[mid]]->end) { - right = mid; - mid = (right - left) / divisorNum + left; + auto lastIt = std::upper_bound(memMapsIndexs_.begin(), memMapsIndexs_.end(), addr, + [this] (uint64_t addr, int index) { + return addr < memMaps_[index]->end; + }); + if (lastIt == memMapsIndexs_.end()) { + return illegal; + } + size_t index = static_cast(std::distance(memMapsIndexs_.begin(), lastIt)); + size_t latestIndex = INT_MAX; + for (; index < memMapsIndexs_.size(); index++) { + if (addr < memMaps_[memMapsIndexs_[index]]->begin || addr >= memMaps_[memMapsIndexs_[index]]->end) { continue; } - if (addr >= memMaps_[memMapsIndexs_[mid]]->end) { - left = mid + 1; - mid = (right - left) / divisorNum + left; + if (latestIndex == INT_MAX) { + latestIndex = index; continue; } + if (onDwarfSymbolizing) { + // first Overlap index is not in OverlapPcMaps, find min index onSymbolizing + latestIndex = memMapsIndexs_[index] < memMapsIndexs_[latestIndex] ? index : latestIndex; + } else { + latestIndex = memMapsIndexs_[index] > memMapsIndexs_[latestIndex] ? index : latestIndex; + } } - if (addr >= memMaps_[memMapsIndexs_[left]]->begin && addr < memMaps_[memMapsIndexs_[left]]->end) { - if (left > 0) { - memMaps_[memMapsIndexs_[left]]->prevMap = memMaps_[memMapsIndexs_[left - 1]]; + if (latestIndex != INT_MAX) { + if (latestIndex > 0) { + memMaps_[memMapsIndexs_[latestIndex]]->prevMap = memMaps_[memMapsIndexs_[latestIndex - 1]]; } - return static_cast(memMapsIndexs_[left]); + OverlapPcMaps.emplace(addr, memMapsIndexs_[latestIndex]); + return static_cast(memMapsIndexs_[latestIndex]); } return illegal; }