From 1ee71e82614edbfe597a388e8a104d1660d0863c Mon Sep 17 00:00:00 2001 From: leiguangyu Date: Wed, 6 Aug 2025 11:10:52 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=84=E7=90=86=E9=87=8D=E5=A4=8Dmaps?= =?UTF-8?q?=EF=BC=8C=E6=8C=89=E5=BA=8F=E4=BF=9D=E5=AD=98pc=E5=92=8Cmaps?= =?UTF-8?q?=E5=AF=B9=E5=BA=94=E5=85=B3=E7=B3=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I1ee04770f47e2147a746df67233e7bd57d2e427e Signed-off-by: leiguangyu --- include/virtual_runtime.h | 2 ++ include/virtual_thread.h | 3 ++- src/subcommand_record.cpp | 1 + src/virtual_runtime.cpp | 9 ++++++-- src/virtual_thread.cpp | 44 +++++++++++++++++++++++++-------------- 5 files changed, 40 insertions(+), 19 deletions(-) diff --git a/include/virtual_runtime.h b/include/virtual_runtime.h index 07bcb36..ab38750 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 89f16a5..938f7a7 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 f147db6..f9bc2e1 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 d211288..1e0572f 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; } -- Gitee