106f6ba60Sopenharmony_ci/* 206f6ba60Sopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. 306f6ba60Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 406f6ba60Sopenharmony_ci * you may not use this file except in compliance with the License. 506f6ba60Sopenharmony_ci * You may obtain a copy of the License at 606f6ba60Sopenharmony_ci * 706f6ba60Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 806f6ba60Sopenharmony_ci * 906f6ba60Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1006f6ba60Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1106f6ba60Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1206f6ba60Sopenharmony_ci * See the License for the specific language governing permissions and 1306f6ba60Sopenharmony_ci * limitations under the License. 1406f6ba60Sopenharmony_ci */ 1506f6ba60Sopenharmony_ci#define HILOG_TAG "Runtime" 1606f6ba60Sopenharmony_ci 1706f6ba60Sopenharmony_ci#include "virtual_runtime.h" 1806f6ba60Sopenharmony_ci 1906f6ba60Sopenharmony_ci#include <cinttypes> 2006f6ba60Sopenharmony_ci#include <iostream> 2106f6ba60Sopenharmony_ci#include <sstream> 2206f6ba60Sopenharmony_ci#include <unistd.h> 2306f6ba60Sopenharmony_ci#if !is_mingw 2406f6ba60Sopenharmony_ci#include <sys/mman.h> 2506f6ba60Sopenharmony_ci#endif 2606f6ba60Sopenharmony_ci 2706f6ba60Sopenharmony_ci#include "dfx_maps.h" 2806f6ba60Sopenharmony_ci#include "register.h" 2906f6ba60Sopenharmony_ci#include "symbols_file.h" 3006f6ba60Sopenharmony_ci#include "utilities.h" 3106f6ba60Sopenharmony_ci 3206f6ba60Sopenharmony_ciusing namespace std::chrono; 3306f6ba60Sopenharmony_cinamespace OHOS { 3406f6ba60Sopenharmony_cinamespace Developtools { 3506f6ba60Sopenharmony_cinamespace NativeDaemon { 3606f6ba60Sopenharmony_cinamespace { 3706f6ba60Sopenharmony_cistd::atomic<uint64_t> callStackErrCnt = 0; 3806f6ba60Sopenharmony_ciconstexpr uint32_t CALL_STACK_ERROR_TIMES = 10; 3906f6ba60Sopenharmony_ciconstexpr uint32_t SYMBOL_FILES_SIZE = 512; 4006f6ba60Sopenharmony_ciconstexpr uint32_t SECOND_INDEX = 2; 4106f6ba60Sopenharmony_ciconstexpr uint32_t THIRD_INDEX = 3; 4206f6ba60Sopenharmony_ciconstexpr uint32_t INFO_SIZE = 4; 4306f6ba60Sopenharmony_ci} 4406f6ba60Sopenharmony_ci// we unable to access 'swapper' from /proc/0/ 4506f6ba60Sopenharmony_civoid VirtualRuntime::ClearMaps() 4606f6ba60Sopenharmony_ci{ 4706f6ba60Sopenharmony_ci processMaps_.clear(); 4806f6ba60Sopenharmony_ci} 4906f6ba60Sopenharmony_ci 5006f6ba60Sopenharmony_ciVirtualRuntime::VirtualRuntime(const NativeHookConfig& hookConfig): hookConfig_(hookConfig) 5106f6ba60Sopenharmony_ci{ 5206f6ba60Sopenharmony_ci symbolsFiles_.reserve(SYMBOL_FILES_SIZE); 5306f6ba60Sopenharmony_ci if (!hookConfig_.offline_symbolization()) { 5406f6ba60Sopenharmony_ci userSymbolCache_.reserve(USER_SYMBOL_CACHE_LIMIT); 5506f6ba60Sopenharmony_ci } 5606f6ba60Sopenharmony_ci} 5706f6ba60Sopenharmony_ci 5806f6ba60Sopenharmony_ciVirtualRuntime::~VirtualRuntime() 5906f6ba60Sopenharmony_ci{ 6006f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "%s:%d UserSymbolCache size = %zu", __func__, __LINE__, userSymbolCache_.size()); 6106f6ba60Sopenharmony_ci PROFILER_LOG_INFO(LOG_CORE, "Total number of call stack errors: %" PRIu64 "", callStackErrCnt.load()); 6206f6ba60Sopenharmony_ci ClearMaps(); 6306f6ba60Sopenharmony_ci} 6406f6ba60Sopenharmony_ci 6506f6ba60Sopenharmony_cistd::string VirtualRuntime::ReadThreadName(pid_t tid) 6606f6ba60Sopenharmony_ci{ 6706f6ba60Sopenharmony_ci std::string comm = ReadFileToString(StringPrintf("/proc/%d/comm", tid)).c_str(); 6806f6ba60Sopenharmony_ci comm.erase(std::remove(comm.begin(), comm.end(), '\r'), comm.end()); 6906f6ba60Sopenharmony_ci comm.erase(std::remove(comm.begin(), comm.end(), '\n'), comm.end()); 7006f6ba60Sopenharmony_ci return comm; 7106f6ba60Sopenharmony_ci} 7206f6ba60Sopenharmony_ci 7306f6ba60Sopenharmony_ciVirtualThread &VirtualRuntime::UpdateThread(pid_t pid, pid_t tid, const std::string name) 7406f6ba60Sopenharmony_ci{ 7506f6ba60Sopenharmony_ci pid_ = pid; 7606f6ba60Sopenharmony_ci#ifdef HIPERF_DEBUG_TIME 7706f6ba60Sopenharmony_ci const auto startTime = steady_clock::now(); 7806f6ba60Sopenharmony_ci#endif 7906f6ba60Sopenharmony_ci VirtualThread &thread = GetThread(pid, tid); 8006f6ba60Sopenharmony_ci if (!name.empty()) { 8106f6ba60Sopenharmony_ci thread.name_ = name; 8206f6ba60Sopenharmony_ci } 8306f6ba60Sopenharmony_ci#ifdef HIPERF_DEBUG_TIME 8406f6ba60Sopenharmony_ci updateThreadTimes_ += duration_cast<microseconds>(steady_clock::now() - startTime); 8506f6ba60Sopenharmony_ci#endif 8606f6ba60Sopenharmony_ci return thread; 8706f6ba60Sopenharmony_ci} 8806f6ba60Sopenharmony_ci 8906f6ba60Sopenharmony_ciVirtualThread &VirtualRuntime::CreateThread(pid_t pid, pid_t tid) 9006f6ba60Sopenharmony_ci{ 9106f6ba60Sopenharmony_ci // make a new one 9206f6ba60Sopenharmony_ci userSpaceThreadMap_.emplace(std::piecewise_construct, std::forward_as_tuple(tid), 9306f6ba60Sopenharmony_ci std::forward_as_tuple(pid, tid, symbolsFiles_, this)); 9406f6ba60Sopenharmony_ci VirtualThread& thr = userSpaceThreadMap_.at(tid); 9506f6ba60Sopenharmony_ci return thr; 9606f6ba60Sopenharmony_ci} 9706f6ba60Sopenharmony_ci 9806f6ba60Sopenharmony_ciVirtualThread &VirtualRuntime::GetThread(pid_t pid, pid_t tid) 9906f6ba60Sopenharmony_ci{ 10006f6ba60Sopenharmony_ci HLOGV("find thread %u:%u", pid, tid); 10106f6ba60Sopenharmony_ci auto it = userSpaceThreadMap_.find(tid); 10206f6ba60Sopenharmony_ci if (it == userSpaceThreadMap_.end()) { 10306f6ba60Sopenharmony_ci // we also need thread 10406f6ba60Sopenharmony_ci VirtualThread& thr = CreateThread(pid, tid); 10506f6ba60Sopenharmony_ci return thr; 10606f6ba60Sopenharmony_ci } else { 10706f6ba60Sopenharmony_ci VirtualThread& thr = it->second; 10806f6ba60Sopenharmony_ci return thr; 10906f6ba60Sopenharmony_ci } 11006f6ba60Sopenharmony_ci} 11106f6ba60Sopenharmony_ci 11206f6ba60Sopenharmony_civoid VirtualRuntime::MakeCallFrame(DfxSymbol &symbol, CallFrame &callFrame) 11306f6ba60Sopenharmony_ci{ 11406f6ba60Sopenharmony_ci callFrame.vaddrInFile_ = symbol.funcVaddr_; 11506f6ba60Sopenharmony_ci callFrame.symbolName_ = symbol.symbolName_; 11606f6ba60Sopenharmony_ci callFrame.symbolIndex_ = symbol.index_; 11706f6ba60Sopenharmony_ci callFrame.filePath_ = symbol.module_.empty() ? symbol.comm_ : symbol.module_; 11806f6ba60Sopenharmony_ci callFrame.symbolOffset_ = symbol.offset_; 11906f6ba60Sopenharmony_ci callFrame.callFrameId_ = symbol.symbolId_; 12006f6ba60Sopenharmony_ci callFrame.symbolNameId_ = symbol.symbolNameId_; 12106f6ba60Sopenharmony_ci callFrame.filePathId_ = symbol.filePathId_; 12206f6ba60Sopenharmony_ci if (symbol.funcVaddr_ != 0) { 12306f6ba60Sopenharmony_ci callFrame.offset_ = symbol.funcVaddr_; 12406f6ba60Sopenharmony_ci } else { 12506f6ba60Sopenharmony_ci callFrame.offset_ = callFrame.ip_; 12606f6ba60Sopenharmony_ci } 12706f6ba60Sopenharmony_ci} 12806f6ba60Sopenharmony_ci 12906f6ba60Sopenharmony_cibool VirtualRuntime::GetSymbolName(pid_t pid, pid_t tid, std::vector<CallFrame>& callFrames, int offset, bool first, 13006f6ba60Sopenharmony_ci bool onlyjs) 13106f6ba60Sopenharmony_ci{ 13206f6ba60Sopenharmony_ci#ifdef HIPERF_DEBUG_TIME 13306f6ba60Sopenharmony_ci const auto startTime = steady_clock::now(); 13406f6ba60Sopenharmony_ci#endif 13506f6ba60Sopenharmony_ci // Symbolic the Call Stack 13606f6ba60Sopenharmony_ci HLOGV("total %zu frames", callFrames.size()); 13706f6ba60Sopenharmony_ci 13806f6ba60Sopenharmony_ci perf_callchain_context perfCallchainContext = PERF_CONTEXT_MAX; 13906f6ba60Sopenharmony_ci for (auto callFrameIt = callFrames.begin() + offset; callFrameIt != callFrames.end(); ++callFrameIt) { 14006f6ba60Sopenharmony_ci auto &callFrame = callFrameIt.operator*(); 14106f6ba60Sopenharmony_ci if (onlyjs && !callFrame.isJsFrame_) { 14206f6ba60Sopenharmony_ci // only symbolize arkts frame 14306f6ba60Sopenharmony_ci continue; 14406f6ba60Sopenharmony_ci } 14506f6ba60Sopenharmony_ci if (callFrame.ip_ >= PERF_CONTEXT_MAX) { 14606f6ba60Sopenharmony_ci // dont care, this is not issue. 14706f6ba60Sopenharmony_ci HLOGV("%s", UpdatePerfContext(callFrame.ip_, perfCallchainContext).c_str()); 14806f6ba60Sopenharmony_ci continue; 14906f6ba60Sopenharmony_ci } 15006f6ba60Sopenharmony_ci auto symbol = GetSymbol(callFrame, pid, tid, 15106f6ba60Sopenharmony_ci perfCallchainContext); 15206f6ba60Sopenharmony_ci if (symbol.IsValid()) { 15306f6ba60Sopenharmony_ci MakeCallFrame(symbol, callFrame); 15406f6ba60Sopenharmony_ci } else { 15506f6ba60Sopenharmony_ci#ifdef TRY_UNWIND_TWICE 15606f6ba60Sopenharmony_ci if (first) { 15706f6ba60Sopenharmony_ci if (failedIPs_.find(callFrame.ip_) == failedIPs_.end()) { 15806f6ba60Sopenharmony_ci return false; 15906f6ba60Sopenharmony_ci } else { 16006f6ba60Sopenharmony_ci callFrames.erase(callFrameIt, callFrames.end()); 16106f6ba60Sopenharmony_ci return true; 16206f6ba60Sopenharmony_ci } 16306f6ba60Sopenharmony_ci } else { 16406f6ba60Sopenharmony_ci failedIPs_.insert(callFrame.ip_); 16506f6ba60Sopenharmony_ci callFrames.erase(callFrameIt, callFrames.end()); 16606f6ba60Sopenharmony_ci return true; 16706f6ba60Sopenharmony_ci } 16806f6ba60Sopenharmony_ci#else 16906f6ba60Sopenharmony_ci ++callStackErrCnt; 17006f6ba60Sopenharmony_ci if (callStackErrCnt.load() % CALL_STACK_ERROR_TIMES == 0) { 17106f6ba60Sopenharmony_ci PROFILER_LOG_DEBUG(LOG_CORE, "number of call stack errors: %" PRIu64 "", callStackErrCnt.load()); 17206f6ba60Sopenharmony_ci } 17306f6ba60Sopenharmony_ci if (callFrames.back().isJsFrame_) { //The fp mode js call stack is behind the native 17406f6ba60Sopenharmony_ci //call stack, so it can't be deleted entirely 17506f6ba60Sopenharmony_ci callFrameIt = callFrames.erase(callFrameIt); 17606f6ba60Sopenharmony_ci --callFrameIt; 17706f6ba60Sopenharmony_ci continue; 17806f6ba60Sopenharmony_ci } 17906f6ba60Sopenharmony_ci callFrames.erase(callFrameIt, callFrames.end()); 18006f6ba60Sopenharmony_ci return true; 18106f6ba60Sopenharmony_ci#endif 18206f6ba60Sopenharmony_ci } 18306f6ba60Sopenharmony_ci int index = callFrameIt - callFrames.begin(); 18406f6ba60Sopenharmony_ci HLOGV(" (%u)unwind symbol: %*s%s", index, index, "", callFrame.ToSymbolString().c_str()); 18506f6ba60Sopenharmony_ci } 18606f6ba60Sopenharmony_ci#ifdef HIPERF_DEBUG_TIME 18706f6ba60Sopenharmony_ci auto usedTime = duration_cast<microseconds>(steady_clock::now() - startTime); 18806f6ba60Sopenharmony_ci if (usedTime.count() != 0) { 18906f6ba60Sopenharmony_ci HLOGV("cost %0.3f ms to symbolic ", usedTime.count() / MS_DUARTION); 19006f6ba60Sopenharmony_ci } 19106f6ba60Sopenharmony_ci symbolicRecordTimes_ += usedTime; 19206f6ba60Sopenharmony_ci#endif 19306f6ba60Sopenharmony_ci return true; 19406f6ba60Sopenharmony_ci} 19506f6ba60Sopenharmony_ci 19606f6ba60Sopenharmony_civoid VirtualRuntime::UpdateMaps(pid_t pid, pid_t tid) 19706f6ba60Sopenharmony_ci{ 19806f6ba60Sopenharmony_ci auto &thread = UpdateThread(pid, tid); 19906f6ba60Sopenharmony_ci if (thread.ParseMap(processMaps_, true)) { 20006f6ba60Sopenharmony_ci PROFILER_LOG_DEBUG(LOG_CORE, "voluntarily update maps succeed"); 20106f6ba60Sopenharmony_ci } else { 20206f6ba60Sopenharmony_ci PROFILER_LOG_DEBUG(LOG_CORE, "voluntarily update maps ignore"); 20306f6ba60Sopenharmony_ci } 20406f6ba60Sopenharmony_ci} 20506f6ba60Sopenharmony_ci 20606f6ba60Sopenharmony_cibool VirtualRuntime::UnwindStack(std::vector<u64>& regs, 20706f6ba60Sopenharmony_ci const u8* stack_addr, 20806f6ba60Sopenharmony_ci int stack_size, 20906f6ba60Sopenharmony_ci pid_t pid, 21006f6ba60Sopenharmony_ci pid_t tid, 21106f6ba60Sopenharmony_ci std::vector<CallFrame>& callFrames, 21206f6ba60Sopenharmony_ci size_t maxStackLevel) 21306f6ba60Sopenharmony_ci{ 21406f6ba60Sopenharmony_ci#ifdef HIPERF_DEBUG_TIME 21506f6ba60Sopenharmony_ci const auto startTime = steady_clock::now(); 21606f6ba60Sopenharmony_ci#endif 21706f6ba60Sopenharmony_ci // if we have userstack ? 21806f6ba60Sopenharmony_ci int offset = 0; 21906f6ba60Sopenharmony_ci auto &thread = UpdateThread(pid, tid); 22006f6ba60Sopenharmony_ci if (stack_size > 0) { 22106f6ba60Sopenharmony_ci callstack_.UnwindCallStack(thread, ®s[0], regs.size(), stack_addr, stack_size, callFrames, maxStackLevel, 22206f6ba60Sopenharmony_ci hookConfig_.js_stack_report() > 0 ? hookConfig_.max_js_stack_depth() : 0, 22306f6ba60Sopenharmony_ci hookConfig_.js_stack_report() > 0); 22406f6ba60Sopenharmony_ci if (callFrames.size() <= FILTER_STACK_DEPTH) { 22506f6ba60Sopenharmony_ci callFrames.clear(); 22606f6ba60Sopenharmony_ci return false; 22706f6ba60Sopenharmony_ci } 22806f6ba60Sopenharmony_ci // Do not symbolize the first two frame, cause the two frame implement by tool itself 22906f6ba60Sopenharmony_ci offset = FILTER_STACK_DEPTH; 23006f6ba60Sopenharmony_ci#ifdef HIPERF_DEBUG_TIME 23106f6ba60Sopenharmony_ci unwindCallStackTimes_ += duration_cast<microseconds>(steady_clock::now() - startTime); 23206f6ba60Sopenharmony_ci#endif 23306f6ba60Sopenharmony_ci } 23406f6ba60Sopenharmony_ci#ifdef HIPERF_DEBUG_TIME 23506f6ba60Sopenharmony_ci unwindFromRecordTimes_ += duration_cast<microseconds>(steady_clock::now() - startTime); 23606f6ba60Sopenharmony_ci#endif 23706f6ba60Sopenharmony_ci if (hookConfig_.offline_symbolization()) { 23806f6ba60Sopenharmony_ci // only get js symbol if report js frame and offline symbolization for dwarf mode 23906f6ba60Sopenharmony_ci if (hookConfig_.js_stack_report() > 0 && !hookConfig_.fp_unwind()) { 24006f6ba60Sopenharmony_ci GetSymbolName(pid, tid, callFrames, offset, true, true); 24106f6ba60Sopenharmony_ci } 24206f6ba60Sopenharmony_ci return true; 24306f6ba60Sopenharmony_ci } 24406f6ba60Sopenharmony_ci if (!GetSymbolName(pid, tid, callFrames, offset, true)) { 24506f6ba60Sopenharmony_ci#ifdef TRY_UNWIND_TWICE 24606f6ba60Sopenharmony_ci HLOGD("clear and unwind one more time"); 24706f6ba60Sopenharmony_ci if (!thread.ParseMap(processMaps_, true)) { 24806f6ba60Sopenharmony_ci GetSymbolName(pid, tid, callFrames, offset, false); 24906f6ba60Sopenharmony_ci return false; 25006f6ba60Sopenharmony_ci } 25106f6ba60Sopenharmony_ci if (stack_size > 0) { 25206f6ba60Sopenharmony_ci callFrames.clear(); 25306f6ba60Sopenharmony_ci callstack_.UnwindCallStack(thread, ®s[0], regs.size(), stack_addr, 25406f6ba60Sopenharmony_ci stack_size, callFrames, maxStackLevel, 0, hookConfig_.js_stack_report() > 0); 25506f6ba60Sopenharmony_ci } 25606f6ba60Sopenharmony_ci if (callFrames.size() <= FILTER_STACK_DEPTH) { 25706f6ba60Sopenharmony_ci callFrames.clear(); 25806f6ba60Sopenharmony_ci return false; 25906f6ba60Sopenharmony_ci } 26006f6ba60Sopenharmony_ci if (!GetSymbolName(pid, tid, callFrames, offset, false)) { 26106f6ba60Sopenharmony_ci return false; 26206f6ba60Sopenharmony_ci } 26306f6ba60Sopenharmony_ci#endif 26406f6ba60Sopenharmony_ci } 26506f6ba60Sopenharmony_ci return true; 26606f6ba60Sopenharmony_ci} 26706f6ba60Sopenharmony_ci 26806f6ba60Sopenharmony_cibool VirtualRuntime::IsSymbolExist(const std::string& fileName) 26906f6ba60Sopenharmony_ci{ 27006f6ba60Sopenharmony_ci if (symbolsFiles_.find(fileName) != symbolsFiles_.end()) { 27106f6ba60Sopenharmony_ci HLOGV("already have '%s'", fileName.c_str()); 27206f6ba60Sopenharmony_ci return true; 27306f6ba60Sopenharmony_ci } 27406f6ba60Sopenharmony_ci return false; 27506f6ba60Sopenharmony_ci} 27606f6ba60Sopenharmony_ci 27706f6ba60Sopenharmony_civoid VirtualRuntime::DelSymbolFile(const std::string& fileName) 27806f6ba60Sopenharmony_ci{ 27906f6ba60Sopenharmony_ci symbolsFiles_.erase(fileName); 28006f6ba60Sopenharmony_ci} 28106f6ba60Sopenharmony_ci 28206f6ba60Sopenharmony_civoid VirtualRuntime::UpdateSymbols(std::string fileName, std::shared_ptr<DfxMap> map) 28306f6ba60Sopenharmony_ci{ 28406f6ba60Sopenharmony_ci HLOGD("try to find symbols for file: %s", fileName.c_str()); 28506f6ba60Sopenharmony_ci#ifdef HIPERF_DEBUG_TIME 28606f6ba60Sopenharmony_ci const auto startTime = steady_clock::now(); 28706f6ba60Sopenharmony_ci#endif 28806f6ba60Sopenharmony_ci if (symbolsFiles_.find(fileName) != symbolsFiles_.end()) { 28906f6ba60Sopenharmony_ci HLOGV("already have '%s'", fileName.c_str()); 29006f6ba60Sopenharmony_ci return; 29106f6ba60Sopenharmony_ci } 29206f6ba60Sopenharmony_ci 29306f6ba60Sopenharmony_ci // found it by name 29406f6ba60Sopenharmony_ci auto symbolsFile = SymbolsFile::CreateSymbolsFile(fileName, pid_); 29506f6ba60Sopenharmony_ci symbolsFile->SetMapsInfo(map); 29606f6ba60Sopenharmony_ci // set sybol path If it exists 29706f6ba60Sopenharmony_ci if (symbolsPaths_.size() > 0) { 29806f6ba60Sopenharmony_ci symbolsFile->setSymbolsFilePath(symbolsPaths_); // also load from search path 29906f6ba60Sopenharmony_ci } 30006f6ba60Sopenharmony_ci if (loadSymboleWhenNeeded_) { 30106f6ba60Sopenharmony_ci // load it when we need it 30206f6ba60Sopenharmony_ci symbolsFiles_[symbolsFile->filePath_] = std::move(symbolsFile); 30306f6ba60Sopenharmony_ci } else if (symbolsFile->LoadSymbols()) { 30406f6ba60Sopenharmony_ci symbolsFiles_[symbolsFile->filePath_] = std::move(symbolsFile); 30506f6ba60Sopenharmony_ci } else { 30606f6ba60Sopenharmony_ci HLOGW("symbols file for '%s' not found.", fileName.c_str()); 30706f6ba60Sopenharmony_ci } 30806f6ba60Sopenharmony_ci#ifdef HIPERF_DEBUG_TIME 30906f6ba60Sopenharmony_ci auto usedTime = duration_cast<microseconds>(steady_clock::now() - startTime); 31006f6ba60Sopenharmony_ci if (usedTime.count() != 0) { 31106f6ba60Sopenharmony_ci HLOGV("cost %0.3f ms to load '%s'", usedTime.count() / MS_DUARTION, fileName.c_str()); 31206f6ba60Sopenharmony_ci } 31306f6ba60Sopenharmony_ci updateSymbolsTimes_ += usedTime; 31406f6ba60Sopenharmony_ci#endif 31506f6ba60Sopenharmony_ci} 31606f6ba60Sopenharmony_ci 31706f6ba60Sopenharmony_cibool VirtualRuntime::UpdateHapSymbols(std::shared_ptr<DfxMap> map) 31806f6ba60Sopenharmony_ci{ 31906f6ba60Sopenharmony_ci auto symbolsFile = SymbolsFile::CreateSymbolsFile(map->name); 32006f6ba60Sopenharmony_ci if (symbolsFile == nullptr) { 32106f6ba60Sopenharmony_ci HLOGV("Failed to load CreateSymbolsFile for exec section in hap(%s)", map->name.c_str()); 32206f6ba60Sopenharmony_ci return false; 32306f6ba60Sopenharmony_ci } 32406f6ba60Sopenharmony_ci symbolsFile->SetMapsInfo(map); 32506f6ba60Sopenharmony_ci // update maps name if load debuginfo successfully 32606f6ba60Sopenharmony_ci if (!symbolsFile->LoadDebugInfo(map)) { 32706f6ba60Sopenharmony_ci HLOGV("Failed to load debuginfo for exec section in hap(%s)", map->name.c_str()); 32806f6ba60Sopenharmony_ci return false; 32906f6ba60Sopenharmony_ci } 33006f6ba60Sopenharmony_ci 33106f6ba60Sopenharmony_ci if (!loadSymboleWhenNeeded_) { 33206f6ba60Sopenharmony_ci symbolsFile->LoadSymbols(map); 33306f6ba60Sopenharmony_ci } 33406f6ba60Sopenharmony_ci symbolsFiles_[symbolsFile->filePath_] = (std::move(symbolsFile)); 33506f6ba60Sopenharmony_ci return true; 33606f6ba60Sopenharmony_ci} 33706f6ba60Sopenharmony_ci 33806f6ba60Sopenharmony_ciconst DfxSymbol VirtualRuntime::GetKernelSymbol(uint64_t ip, const std::vector<std::shared_ptr<DfxMap>> &maps, 33906f6ba60Sopenharmony_ci const VirtualThread &thread) 34006f6ba60Sopenharmony_ci{ 34106f6ba60Sopenharmony_ci DfxSymbol vaddrSymbol(ip, thread.name_); 34206f6ba60Sopenharmony_ci for (auto &map : maps) { 34306f6ba60Sopenharmony_ci if (ip > map->begin && ip < map->end) { 34406f6ba60Sopenharmony_ci HLOGM("found addr 0x%" PRIx64 " in kernel map 0x%" PRIx64 " - 0x%" PRIx64 " from %s", 34506f6ba60Sopenharmony_ci ip, map->begin, map->end, map->name.c_str()); 34606f6ba60Sopenharmony_ci vaddrSymbol.module_ = map->name; 34706f6ba60Sopenharmony_ci // found symbols by file name 34806f6ba60Sopenharmony_ci auto search = symbolsFiles_.find(map->name); 34906f6ba60Sopenharmony_ci if (search != symbolsFiles_.end()) { 35006f6ba60Sopenharmony_ci auto& symbolsFile = search->second; 35106f6ba60Sopenharmony_ci vaddrSymbol.fileVaddr_ = 35206f6ba60Sopenharmony_ci symbolsFile->GetVaddrInSymbols(ip, map->begin, map->offset); 35306f6ba60Sopenharmony_ci HLOGV("found symbol vaddr 0x%" PRIx64 " for runtime vaddr 0x%" PRIx64 35406f6ba60Sopenharmony_ci " at '%s'", 35506f6ba60Sopenharmony_ci vaddrSymbol.fileVaddr_, ip, map->name.c_str()); 35606f6ba60Sopenharmony_ci if (!symbolsFile->SymbolsLoaded()) { 35706f6ba60Sopenharmony_ci symbolsFile->LoadSymbols(map); 35806f6ba60Sopenharmony_ci } 35906f6ba60Sopenharmony_ci DfxSymbol foundSymbols = symbolsFile->GetSymbolWithVaddr(vaddrSymbol.fileVaddr_); 36006f6ba60Sopenharmony_ci foundSymbols.taskVaddr_ = ip; 36106f6ba60Sopenharmony_ci if (!foundSymbols.IsValid()) { 36206f6ba60Sopenharmony_ci HLOGW("addr 0x%" PRIx64 " vaddr 0x%" PRIx64 " NOT found in symbol file %s", 36306f6ba60Sopenharmony_ci ip, vaddrSymbol.fileVaddr_, map->name.c_str()); 36406f6ba60Sopenharmony_ci return vaddrSymbol; 36506f6ba60Sopenharmony_ci } else { 36606f6ba60Sopenharmony_ci return foundSymbols; 36706f6ba60Sopenharmony_ci } 36806f6ba60Sopenharmony_ci } 36906f6ba60Sopenharmony_ci HLOGW("addr 0x%" PRIx64 " in map but NOT found the symbol file %s", ip, 37006f6ba60Sopenharmony_ci map->name.c_str()); 37106f6ba60Sopenharmony_ci } else { 37206f6ba60Sopenharmony_ci HLOGM("addr 0x%" PRIx64 " not in map 0x%" PRIx64 " - 0x%" PRIx64 " from %s", ip, 37306f6ba60Sopenharmony_ci map->begin, map->end, map->name.c_str()); 37406f6ba60Sopenharmony_ci } 37506f6ba60Sopenharmony_ci } 37606f6ba60Sopenharmony_ci return vaddrSymbol; 37706f6ba60Sopenharmony_ci} 37806f6ba60Sopenharmony_ci 37906f6ba60Sopenharmony_ciconst DfxSymbol VirtualRuntime::GetUserSymbol(uint64_t ip, const VirtualThread &thread) 38006f6ba60Sopenharmony_ci{ 38106f6ba60Sopenharmony_ci DfxSymbol vaddrSymbol(ip, thread.name_); 38206f6ba60Sopenharmony_ci auto [curMaps, itemIndex] = FindMap(ip); 38306f6ba60Sopenharmony_ci if (curMaps != nullptr) { 38406f6ba60Sopenharmony_ci auto symbolsFilesIter = symbolsFiles_.find((curMaps->GetMaps())[itemIndex]->name); 38506f6ba60Sopenharmony_ci if (symbolsFilesIter != symbolsFiles_.end()) { 38606f6ba60Sopenharmony_ci auto symbolsFile = symbolsFilesIter->second.get(); 38706f6ba60Sopenharmony_ci symbolsFile->LoadDebugInfo((curMaps->GetMaps())[itemIndex]); 38806f6ba60Sopenharmony_ci vaddrSymbol.fileVaddr_ = 38906f6ba60Sopenharmony_ci symbolsFile->GetVaddrInSymbols(ip, (curMaps->GetMaps())[itemIndex]->begin, 39006f6ba60Sopenharmony_ci (curMaps->GetMaps())[itemIndex]->offset); 39106f6ba60Sopenharmony_ci vaddrSymbol.module_ = (curMaps->GetMaps())[itemIndex]->name; 39206f6ba60Sopenharmony_ci vaddrSymbol.symbolName_ = vaddrSymbol.GetName(); 39306f6ba60Sopenharmony_ci if (!symbolsFile->SymbolsLoaded()) { 39406f6ba60Sopenharmony_ci symbolsFile->LoadSymbols((curMaps->GetMaps())[itemIndex]); 39506f6ba60Sopenharmony_ci } 39606f6ba60Sopenharmony_ci 39706f6ba60Sopenharmony_ci DfxSymbol foundSymbols; 39806f6ba60Sopenharmony_ci 39906f6ba60Sopenharmony_ci if (!symbolsFile->IsAbc()) { 40006f6ba60Sopenharmony_ci foundSymbols = symbolsFile->GetSymbolWithVaddr(vaddrSymbol.fileVaddr_); 40106f6ba60Sopenharmony_ci } else { 40206f6ba60Sopenharmony_ci HLOGD("symbolsFile:%s is ABC :%d", symbolsFile->filePath_.c_str(), symbolsFile->IsAbc()); 40306f6ba60Sopenharmony_ci foundSymbols = symbolsFile->GetSymbolWithPcAndMap(ip, curMaps->GetMaps()[itemIndex]); 40406f6ba60Sopenharmony_ci } 40506f6ba60Sopenharmony_ci foundSymbols.taskVaddr_ = ip; 40606f6ba60Sopenharmony_ci foundSymbols.symbolName_ = foundSymbols.GetName(); 40706f6ba60Sopenharmony_ci if (!foundSymbols.IsValid()) { 40806f6ba60Sopenharmony_ci vaddrSymbol.filePathId_ = curMaps->filePathId_; 40906f6ba60Sopenharmony_ci return vaddrSymbol; 41006f6ba60Sopenharmony_ci } else { 41106f6ba60Sopenharmony_ci foundSymbols.filePathId_ = curMaps->filePathId_; 41206f6ba60Sopenharmony_ci return foundSymbols; 41306f6ba60Sopenharmony_ci } 41406f6ba60Sopenharmony_ci } else { 41506f6ba60Sopenharmony_ci HLOGW("addr 0x%" PRIx64 " in map but NOT found the symbol file %s", ip, 41606f6ba60Sopenharmony_ci curMaps->name_.c_str()); 41706f6ba60Sopenharmony_ci } 41806f6ba60Sopenharmony_ci } else { 41906f6ba60Sopenharmony_ci HLOGW("ReportVaddrMapMiss"); 42006f6ba60Sopenharmony_ci#ifdef HIPERF_DEBUG 42106f6ba60Sopenharmony_ci thread.ReportVaddrMapMiss(ip); 42206f6ba60Sopenharmony_ci#endif 42306f6ba60Sopenharmony_ci } 42406f6ba60Sopenharmony_ci return vaddrSymbol; 42506f6ba60Sopenharmony_ci} 42606f6ba60Sopenharmony_ci 42706f6ba60Sopenharmony_cibool VirtualRuntime::GetSymbolCache(uint64_t ip, DfxSymbol &symbol, const VirtualThread &thread) 42806f6ba60Sopenharmony_ci{ 42906f6ba60Sopenharmony_ci auto [curMaps, itemIndex] = FindMap(ip); 43006f6ba60Sopenharmony_ci if (curMaps != nullptr) { 43106f6ba60Sopenharmony_ci auto foundSymbolIter = userSymbolCache_.find(std::pair(ip, curMaps->filePathId_)); 43206f6ba60Sopenharmony_ci if (foundSymbolIter != userSymbolCache_.end()) { 43306f6ba60Sopenharmony_ci symbol = foundSymbolIter->second; 43406f6ba60Sopenharmony_ci return true; 43506f6ba60Sopenharmony_ci } 43606f6ba60Sopenharmony_ci } 43706f6ba60Sopenharmony_ci return false; 43806f6ba60Sopenharmony_ci} 43906f6ba60Sopenharmony_ci 44006f6ba60Sopenharmony_civoid VirtualRuntime::UpdateSymbolCache(uint64_t ip, DfxSymbol &symbol, 44106f6ba60Sopenharmony_ci HashList<uint64_t, DfxSymbol> &cache) 44206f6ba60Sopenharmony_ci{ 44306f6ba60Sopenharmony_ci // review change to LRU for memmory 44406f6ba60Sopenharmony_ci HLOG_ASSERT_MESSAGE(cache.count(ip) == 0, "already have cached ip 0x%" PRIx64 "", ip); 44506f6ba60Sopenharmony_ci cache[ip] = symbol; 44606f6ba60Sopenharmony_ci} 44706f6ba60Sopenharmony_ci 44806f6ba60Sopenharmony_ciconst DfxSymbol VirtualRuntime::GetSymbol(CallFrame& callFrame, pid_t pid, pid_t tid, 44906f6ba60Sopenharmony_ci const perf_callchain_context &context) 45006f6ba60Sopenharmony_ci{ 45106f6ba60Sopenharmony_ci HLOGM("try find tid %u ip 0x%" PRIx64 " in %zu symbolsFiles ", tid, callFrame.ip_, symbolsFiles_.size()); 45206f6ba60Sopenharmony_ci DfxSymbol symbol; 45306f6ba60Sopenharmony_ci if (hookConfig_.fp_unwind() && callFrame.isJsFrame_) { 45406f6ba60Sopenharmony_ci if (ArktsGetSymbolCache(callFrame, symbol)) { 45506f6ba60Sopenharmony_ci return symbol; 45606f6ba60Sopenharmony_ci } else { 45706f6ba60Sopenharmony_ci symbol.filePathId_ = FillArkTsFilePath(callFrame.filePath_); 45806f6ba60Sopenharmony_ci symbol.module_ = callFrame.filePath_; 45906f6ba60Sopenharmony_ci symbol.symbolName_ = callFrame.symbolName_; 46006f6ba60Sopenharmony_ci symbol.symbolId_ = userSymbolCache_.size() + 1; 46106f6ba60Sopenharmony_ci if (hookConfig_.string_compressed()) { 46206f6ba60Sopenharmony_ci FillSymbolNameId(callFrame, symbol); 46306f6ba60Sopenharmony_ci FillFileSet(callFrame, symbol); 46406f6ba60Sopenharmony_ci } 46506f6ba60Sopenharmony_ci callFrame.needReport_ |= CALL_FRAME_REPORT; 46606f6ba60Sopenharmony_ci userSymbolCache_[std::pair(callFrame.ip_, symbol.filePathId_)] = symbol; 46706f6ba60Sopenharmony_ci return symbol; 46806f6ba60Sopenharmony_ci } 46906f6ba60Sopenharmony_ci } else if (GetSymbolCache(callFrame.ip_, symbol, GetThread(pid, tid))) { 47006f6ba60Sopenharmony_ci return symbol; 47106f6ba60Sopenharmony_ci } 47206f6ba60Sopenharmony_ci if (context == PERF_CONTEXT_USER or (context == PERF_CONTEXT_MAX and !symbol.IsValid())) { 47306f6ba60Sopenharmony_ci // check userspace memmap 47406f6ba60Sopenharmony_ci symbol = GetUserSymbol(callFrame.ip_, GetThread(pid, tid)); 47506f6ba60Sopenharmony_ci if (symbol.IsValid()) { 47606f6ba60Sopenharmony_ci HLOGM("GetUserSymbol valid tid = %d ip = 0x%" PRIx64 "", tid, callFrame.ip_); 47706f6ba60Sopenharmony_ci symbol.symbolId_ = userSymbolCache_.size() + 1; 47806f6ba60Sopenharmony_ci if (hookConfig_.string_compressed()) { 47906f6ba60Sopenharmony_ci FillSymbolNameId(callFrame, symbol); 48006f6ba60Sopenharmony_ci FillFileSet(callFrame, symbol); 48106f6ba60Sopenharmony_ci } 48206f6ba60Sopenharmony_ci callFrame.needReport_ |= CALL_FRAME_REPORT; 48306f6ba60Sopenharmony_ci userSymbolCache_[std::pair(callFrame.ip_, symbol.filePathId_)] = symbol; 48406f6ba60Sopenharmony_ci } else { 48506f6ba60Sopenharmony_ci HLOGM("GetUserSymbol invalid!"); 48606f6ba60Sopenharmony_ci } 48706f6ba60Sopenharmony_ci } 48806f6ba60Sopenharmony_ci 48906f6ba60Sopenharmony_ci return symbol; 49006f6ba60Sopenharmony_ci} 49106f6ba60Sopenharmony_ci 49206f6ba60Sopenharmony_cibool VirtualRuntime::SetSymbolsPaths(const std::vector<std::string> &symbolsPaths) 49306f6ba60Sopenharmony_ci{ 49406f6ba60Sopenharmony_ci std::unique_ptr<SymbolsFile> symbolsFile = SymbolsFile::CreateSymbolsFile(SYMBOL_UNKNOW_FILE); 49506f6ba60Sopenharmony_ci // we need check if the path is accessable 49606f6ba60Sopenharmony_ci bool accessable = symbolsFile->setSymbolsFilePath(symbolsPaths); 49706f6ba60Sopenharmony_ci if (accessable) { 49806f6ba60Sopenharmony_ci symbolsPaths_ = symbolsPaths; 49906f6ba60Sopenharmony_ci } else { 50006f6ba60Sopenharmony_ci if (!symbolsPaths.empty()) { 50106f6ba60Sopenharmony_ci printf("some symbols path unable access\n"); 50206f6ba60Sopenharmony_ci } 50306f6ba60Sopenharmony_ci } 50406f6ba60Sopenharmony_ci return accessable; 50506f6ba60Sopenharmony_ci} 50606f6ba60Sopenharmony_ci 50706f6ba60Sopenharmony_civoid VirtualRuntime::FillMapsCache(std::string& currentFileName, std::shared_ptr<DfxMap> mapItem) 50806f6ba60Sopenharmony_ci{ 50906f6ba60Sopenharmony_ci if (currentFileName.compare(mapItem->name) != 0) { 51006f6ba60Sopenharmony_ci currentFileName = mapItem->name; 51106f6ba60Sopenharmony_ci soBegin_ = mapItem->begin; 51206f6ba60Sopenharmony_ci auto memMaps = std::make_shared<MemMaps>(++memMapFilePathId_); 51306f6ba60Sopenharmony_ci memMaps->AddMap(mapItem, true); 51406f6ba60Sopenharmony_ci mapsCache_[mapItem->begin] = memMaps; 51506f6ba60Sopenharmony_ci } else { 51606f6ba60Sopenharmony_ci if (auto curMapsIter = mapsCache_.find(soBegin_); 51706f6ba60Sopenharmony_ci curMapsIter != mapsCache_.end()) { 51806f6ba60Sopenharmony_ci auto& curMaps = curMapsIter->second; 51906f6ba60Sopenharmony_ci curMaps->soEnd_ = mapItem->end; 52006f6ba60Sopenharmony_ci curMaps->AddMap(mapItem, false); 52106f6ba60Sopenharmony_ci if (mapItem->prots & PROT_EXEC) { 52206f6ba60Sopenharmony_ci offlineMapAddr_.push_back(soBegin_); 52306f6ba60Sopenharmony_ci } 52406f6ba60Sopenharmony_ci } 52506f6ba60Sopenharmony_ci } 52606f6ba60Sopenharmony_ci} 52706f6ba60Sopenharmony_ci 52806f6ba60Sopenharmony_civoid VirtualRuntime::FillSymbolNameId(CallFrame& callFrame, DfxSymbol& symbol) 52906f6ba60Sopenharmony_ci{ 53006f6ba60Sopenharmony_ci auto itFuntion = functionMap_.find(std::string(symbol.symbolName_)); 53106f6ba60Sopenharmony_ci if (itFuntion != functionMap_.end()) { 53206f6ba60Sopenharmony_ci symbol.symbolNameId_ = itFuntion->second; 53306f6ba60Sopenharmony_ci } else { 53406f6ba60Sopenharmony_ci symbol.symbolNameId_ = functionMap_.size() + 1; 53506f6ba60Sopenharmony_ci functionMap_[std::string(symbol.symbolName_)] = symbol.symbolNameId_; 53606f6ba60Sopenharmony_ci callFrame.needReport_ |= SYMBOL_NAME_ID_REPORT; 53706f6ba60Sopenharmony_ci } 53806f6ba60Sopenharmony_ci} 53906f6ba60Sopenharmony_ci 54006f6ba60Sopenharmony_civoid VirtualRuntime::FillFileSet(CallFrame& callFrame, const DfxSymbol& symbol) 54106f6ba60Sopenharmony_ci{ 54206f6ba60Sopenharmony_ci auto itFile = fileSet_.find(symbol.filePathId_); 54306f6ba60Sopenharmony_ci if (itFile == fileSet_.end()) { 54406f6ba60Sopenharmony_ci callFrame.needReport_ |= FILE_PATH_ID_REPORT; 54506f6ba60Sopenharmony_ci fileSet_.insert(symbol.filePathId_); 54606f6ba60Sopenharmony_ci } 54706f6ba60Sopenharmony_ci} 54806f6ba60Sopenharmony_ci 54906f6ba60Sopenharmony_civoid VirtualRuntime::HandleMapInfo(std::vector<uint64_t> info, const std::string& filePath, pid_t pid, pid_t tid) 55006f6ba60Sopenharmony_ci{ 55106f6ba60Sopenharmony_ci if (info.size() != INFO_SIZE) { 55206f6ba60Sopenharmony_ci return; 55306f6ba60Sopenharmony_ci } 55406f6ba60Sopenharmony_ci uint64_t begin = info[0]; 55506f6ba60Sopenharmony_ci uint64_t length = info[1]; 55606f6ba60Sopenharmony_ci uint64_t flags = info[SECOND_INDEX]; 55706f6ba60Sopenharmony_ci uint64_t offset = info[THIRD_INDEX]; 55806f6ba60Sopenharmony_ci if (!(flags & MAP_FIXED)) { 55906f6ba60Sopenharmony_ci return; 56006f6ba60Sopenharmony_ci } 56106f6ba60Sopenharmony_ci if (offset == 0 && mapsCache_.find(begin) == mapsCache_.end()) { 56206f6ba60Sopenharmony_ci soBegin_ = begin; 56306f6ba60Sopenharmony_ci std::shared_ptr<DfxMap> mapItem = std::make_shared<DfxMap>(begin, begin + length, offset, flags, filePath); 56406f6ba60Sopenharmony_ci auto memMaps = std::make_shared<MemMaps>(++memMapFilePathId_); 56506f6ba60Sopenharmony_ci memMaps->AddMap(mapItem, true); 56606f6ba60Sopenharmony_ci mapsCache_[begin] = memMaps; 56706f6ba60Sopenharmony_ci UpdateSymbols(filePath, mapItem); 56806f6ba60Sopenharmony_ci if ((!hookConfig_.fp_unwind())) { 56906f6ba60Sopenharmony_ci auto &thread = UpdateThread(pid, tid); 57006f6ba60Sopenharmony_ci thread.ParseMap(processMaps_, false); 57106f6ba60Sopenharmony_ci } 57206f6ba60Sopenharmony_ci } else { 57306f6ba60Sopenharmony_ci auto curMapsIter = mapsCache_.find(soBegin_); 57406f6ba60Sopenharmony_ci if (curMapsIter != mapsCache_.end()) { 57506f6ba60Sopenharmony_ci auto& curMaps = curMapsIter->second; 57606f6ba60Sopenharmony_ci curMaps->soEnd_ = begin + length; 57706f6ba60Sopenharmony_ci std::shared_ptr<DfxMap> mapItem = std::make_shared<DfxMap>(begin, begin + length, 57806f6ba60Sopenharmony_ci offset, flags, curMaps->name_); 57906f6ba60Sopenharmony_ci if (mapItem->name.find(".hap") != std::string::npos && (mapItem->prots & PROT_EXEC)) { 58006f6ba60Sopenharmony_ci mapItem->prevMap = curMaps->GetMaps().back(); 58106f6ba60Sopenharmony_ci HLOGD("update hap(%s) symbols", mapItem->name.c_str()); 58206f6ba60Sopenharmony_ci UpdateHapSymbols(mapItem); 58306f6ba60Sopenharmony_ci } 58406f6ba60Sopenharmony_ci curMaps->AddMap(mapItem, false); 58506f6ba60Sopenharmony_ci } 58606f6ba60Sopenharmony_ci } 58706f6ba60Sopenharmony_ci if (flags & PROT_EXEC) { 58806f6ba60Sopenharmony_ci offlineMapAddr_.push_back(soBegin_); 58906f6ba60Sopenharmony_ci } 59006f6ba60Sopenharmony_ci} 59106f6ba60Sopenharmony_ci 59206f6ba60Sopenharmony_civoid VirtualRuntime::RemoveMaps(uint64_t addr) 59306f6ba60Sopenharmony_ci{ 59406f6ba60Sopenharmony_ci mapsCache_.erase(addr); 59506f6ba60Sopenharmony_ci} 59606f6ba60Sopenharmony_ci 59706f6ba60Sopenharmony_cistd::pair<std::shared_ptr<MemMaps>, uint32_t> VirtualRuntime::FindMap(uint64_t addr) 59806f6ba60Sopenharmony_ci{ 59906f6ba60Sopenharmony_ci auto iter = mapsCache_.upper_bound(addr); 60006f6ba60Sopenharmony_ci if (iter == mapsCache_.begin()) { 60106f6ba60Sopenharmony_ci // have map 2 3 4 5 60206f6ba60Sopenharmony_ci // find 1 , will return 2 (index 0, begin elem) 60306f6ba60Sopenharmony_ci // this same as not found any thins 60406f6ba60Sopenharmony_ci return {nullptr, 0}; 60506f6ba60Sopenharmony_ci } 60606f6ba60Sopenharmony_ci 60706f6ba60Sopenharmony_ci std::shared_ptr<MemMaps> curMaps = (--iter)->second; 60806f6ba60Sopenharmony_ci if (addr >= curMaps->soBegin_ && addr < curMaps->soEnd_) { 60906f6ba60Sopenharmony_ci std::vector<std::shared_ptr<DfxMap>> mapVec = curMaps->GetMaps(); 61006f6ba60Sopenharmony_ci for (auto curMapItem = mapVec.begin(); 61106f6ba60Sopenharmony_ci curMapItem != mapVec.end(); ++curMapItem) { 61206f6ba60Sopenharmony_ci if (addr >= (*curMapItem)->begin && addr < (*curMapItem)->end) { 61306f6ba60Sopenharmony_ci return {curMaps, curMapItem - mapVec.begin()}; 61406f6ba60Sopenharmony_ci } 61506f6ba60Sopenharmony_ci } 61606f6ba60Sopenharmony_ci } 61706f6ba60Sopenharmony_ci return {nullptr, 0}; 61806f6ba60Sopenharmony_ci} 61906f6ba60Sopenharmony_ci 62006f6ba60Sopenharmony_cibool VirtualRuntime::ArktsGetSymbolCache(CallFrame& callFrame, DfxSymbol &symbol) 62106f6ba60Sopenharmony_ci{ 62206f6ba60Sopenharmony_ci uint32_t jsfilePathId = FindArkTsFilePath(callFrame.filePath_); 62306f6ba60Sopenharmony_ci if (jsfilePathId != 0) { 62406f6ba60Sopenharmony_ci auto foundSymbolIter = userSymbolCache_.find(std::pair(callFrame.ip_, jsfilePathId)); 62506f6ba60Sopenharmony_ci if (foundSymbolIter != userSymbolCache_.end()) { 62606f6ba60Sopenharmony_ci symbol = foundSymbolIter->second; 62706f6ba60Sopenharmony_ci return true; 62806f6ba60Sopenharmony_ci } 62906f6ba60Sopenharmony_ci } 63006f6ba60Sopenharmony_ci return false; 63106f6ba60Sopenharmony_ci} 63206f6ba60Sopenharmony_ci 63306f6ba60Sopenharmony_ciuint32_t VirtualRuntime::FindArkTsFilePath(std::string_view& jstr) 63406f6ba60Sopenharmony_ci{ 63506f6ba60Sopenharmony_ci auto iter = jsUrlMap_.find(jstr); 63606f6ba60Sopenharmony_ci if (iter == jsUrlMap_.end()) { 63706f6ba60Sopenharmony_ci return 0; 63806f6ba60Sopenharmony_ci } else { 63906f6ba60Sopenharmony_ci return iter->second; 64006f6ba60Sopenharmony_ci } 64106f6ba60Sopenharmony_ci} 64206f6ba60Sopenharmony_ci 64306f6ba60Sopenharmony_ciuint32_t VirtualRuntime::FillArkTsFilePath(std::string_view& jstr) 64406f6ba60Sopenharmony_ci{ 64506f6ba60Sopenharmony_ci auto iter = jsUrlMap_.find(jstr); 64606f6ba60Sopenharmony_ci if (iter == jsUrlMap_.end()) { 64706f6ba60Sopenharmony_ci jsUrlMap_[jstr] = ++memMapFilePathId_; 64806f6ba60Sopenharmony_ci } 64906f6ba60Sopenharmony_ci return jsUrlMap_[jstr]; 65006f6ba60Sopenharmony_ci} 65106f6ba60Sopenharmony_ci 65206f6ba60Sopenharmony_civoid VirtualRuntime::FillJsSymbolCache(CallFrame& callFrame, const DfxSymbol& symbol) 65306f6ba60Sopenharmony_ci{ 65406f6ba60Sopenharmony_ci userSymbolCache_[std::pair(callFrame.ip_, symbol.filePathId_)] = symbol; 65506f6ba60Sopenharmony_ci} 65606f6ba60Sopenharmony_ci 65706f6ba60Sopenharmony_ciuint32_t VirtualRuntime::GetJsSymbolCacheSize() 65806f6ba60Sopenharmony_ci{ 65906f6ba60Sopenharmony_ci return userSymbolCache_.size() + 1; 66006f6ba60Sopenharmony_ci} 66106f6ba60Sopenharmony_ci 66206f6ba60Sopenharmony_ci} // namespace NativeDaemon 66306f6ba60Sopenharmony_ci} // namespace Developtools 66406f6ba60Sopenharmony_ci} // namespace OHOS 665