From f29140ab4b13658fe4d246f93dff425fcebc3df0 Mon Sep 17 00:00:00 2001 From: "lijindong (C)" <2220386943@qq.com> Date: Thu, 4 Dec 2025 16:00:44 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=B9=E6=8D=AEmnt=EF=BC=8C=E8=AF=BB?= =?UTF-8?q?=E5=8F=96=E5=AF=B9=E5=BA=94=E7=9A=84mntPoint=EF=BC=8C=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=E6=97=A0=E6=B3=95=E8=A7=A3=E6=9E=90=E5=AE=B9=E5=99=A8?= =?UTF-8?q?=E7=AC=A6=E5=8F=B7=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- symbol/symbol.h | 3 +- symbol/symbol_resolve.cpp | 177 ++++++++++++++++---------------------- symbol/symbol_resolve.h | 7 +- util/common.cpp | 78 +++++++++++++++++ util/common.h | 2 +- 5 files changed, 159 insertions(+), 108 deletions(-) diff --git a/symbol/symbol.h b/symbol/symbol.h index 235df4b..9504fff 100644 --- a/symbol/symbol.h +++ b/symbol/symbol.h @@ -30,14 +30,13 @@ struct Symbol { unsigned long offset; unsigned long codeMapEndAddr; // function end address unsigned long codeMapAddr; // real srcAddr of Asm Code or - __u64 count; + char* mntPoint; // mount point }; struct Stack { struct Symbol* symbol; // symbol info for current stack struct Stack* next; // points to next position in stack struct Stack* prev; // points to previous position in stack - __u64 count; } __attribute__((aligned(64))); struct StackAsm { diff --git a/symbol/symbol_resolve.cpp b/symbol/symbol_resolve.cpp index 70aa079..185dce8 100644 --- a/symbol/symbol_resolve.cpp +++ b/symbol/symbol_resolve.cpp @@ -100,6 +100,7 @@ namespace { symbol->symbolName = UNKNOWN; symbol->mangleName = UNKNOWN; symbol->fileName = UNKNOWN; + symbol->mntPoint = nullptr; symbol->addr = addr; symbol->offset = 0; symbol->lineNum = 0; @@ -217,22 +218,6 @@ namespace { return asmCode; } - static inline void FreeSymMap(SYMBOL_MAP& symMap) - { - for (auto& item : symMap) { - for (auto& data : item.second) { - SymbolUtils::FreeSymbol(data.second); - } - } - } - - static inline void FreeSymUnmap(SYMBOL_UNMAP& symMap) - { - for (auto& item : symMap) { - SymbolUtils::FreeSymbol(item); - } - } - static inline void FreeStackMap(STACK_MAP& stackMap) { for (auto& item : stackMap) { @@ -243,28 +228,6 @@ namespace { } } - static inline void FreeKernelVet(std::vector>& kernel) - { - for (auto symbol : kernel) { - if (symbol->module) { - delete[] symbol->module; - symbol->module = nullptr; - } - if (symbol->fileName) { - delete[] symbol->fileName; - symbol->fileName = nullptr; - } - if (symbol->symbolName) { - delete[] symbol->symbolName; - symbol->symbolName = nullptr; - } - if (symbol->mangleName) { - delete[] symbol->mangleName; - symbol->mangleName = nullptr; - } - } - } - static inline std::string HashStr(unsigned long* stack, int nr) { std::string str = {}; @@ -292,32 +255,6 @@ namespace { } // namespace -void SymbolUtils::FreeSymbol(struct Symbol* symbol) -{ - if (symbol->symbolName && symbol->symbolName != UNKNOWN) { - delete[] symbol->symbolName; - symbol->symbolName = nullptr; - } - - if (symbol->mangleName && symbol->mangleName != UNKNOWN) { - delete[] symbol->mangleName; - symbol->mangleName = nullptr; - } - - if (symbol->fileName && symbol->fileName != UNKNOWN && symbol->fileName != KERNEL) { - delete[] symbol->fileName; - symbol->fileName = nullptr; - } - if (symbol->module && symbol->module != UNKNOWN && symbol->module != KERNEL) { - delete[] symbol->module; - symbol->module = nullptr; - } - if (symbol) { - delete symbol; - symbol = nullptr; - } -} - void SymbolUtils::FreeStackAsm(struct StackAsm** stackAsm) { struct StackAsm* current = *stackAsm; @@ -367,6 +304,14 @@ bool SymbolUtils::IsNumber(const std::string& str) return true; } +void SymbolUtils::FreeSymbol(struct Symbol* symbol) +{ + if (symbol) { + delete symbol; + symbol = nullptr; + } +} + void SymbolUtils::StrCpy(char* dst, int dstLen, const char* src) { int size = strlen(src) > dstLen ? dstLen + 1 : strlen(src) + 1; @@ -538,10 +483,16 @@ int SymbolResolve::RecordModule(int pid, RecordModuleType recordModuleType) } std::vector> modVec; ReadProcPidMap(file, modVec); + std::string mntPoint = GetMntPoint(pid); for (auto& item : modVec) { - this->RecordElf(item->moduleName.c_str()); + std::string moduleName = item->moduleName; + if (!mntPoint.empty()) { + item->mntPoint = mntPoint; + moduleName = mntPoint + "/" + item->moduleName; + } + this->RecordElf(moduleName.c_str()); if (recordModuleType != RecordModuleType::RECORD_NO_DWARF) { - this->RecordDwarf(item->moduleName.c_str()); + this->RecordDwarf(moduleName.c_str()); } } this->moduleMap.insert({pid, modVec}); @@ -573,7 +524,7 @@ int SymbolResolve::UpdateModule(int pid, RecordModuleType recordModuleType) } std::vector> newModVec; ReadProcPidMap(file, newModVec); - + std::string mntPoint = GetMntPoint(pid); // Find new dynamic modules. auto &oldModVec = moduleMap[pid]; if (newModVec.size() <= oldModVec.size()) { @@ -584,9 +535,14 @@ int SymbolResolve::UpdateModule(int pid, RecordModuleType recordModuleType) auto diffModVec = FindDiffMaps(oldModVec, newModVec); // Load modules. for (auto& item : diffModVec) { - this->RecordElf(item->moduleName.c_str()); + std::string moduleName = item->moduleName; + if (!mntPoint.empty()) { + moduleName = mntPoint + "/" + moduleName; + item->mntPoint = mntPoint; + } + this->RecordElf(moduleName.c_str()); if (recordModuleType != RecordModuleType::RECORD_NO_DWARF) { - this->RecordDwarf(item->moduleName.c_str()); + this->RecordDwarf(moduleName.c_str()); } } for (auto& mod : diffModVec) { @@ -713,19 +669,25 @@ void SymbolResolve::Clear() if (!this->instance) { return; } - /** - * free the memory allocated for symbol table - */ - FreeSymMap(this->symbolMap); - FreeSymUnmap(this->symbolUnmap); + for (auto& item : this->symbolMap) { + for(auto& data : item.second) { + SymbolUtils::FreeSymbol(data.second); + } + } + + for (auto& item: symbolUnmap) { + SymbolUtils::FreeSymbol(item); + } /** * free the memory allocated for stack table */ FreeStackMap(this->stackMap); /** - * free the memory allocated from kernel + * free the strdup data */ - FreeKernelVet(this->ksymArray); + for (auto& item : strToCharMap) { + free(item.second); + } this->isCleared = true; delete this->instance; this->instance = nullptr; @@ -740,18 +702,15 @@ void SymbolResolve::SearchElfInfo(MyElf& myElf, unsigned long addr, struct Symbo symbol->codeMapEndAddr = elfSym->get_data().value + elfSym->get_data().size; *offset = addr - elfSym->get_data().value; std::string symName = elfSym->get_name(); - symbol->mangleName = InitChar(symName.size()); - SymbolUtils::StrCpy(symbol->mangleName, symName.size(), symName.c_str()); + symbol->mangleName = GetCharFromStr(symName); char *name = CppNamedDemangle(symName.c_str()); if (name) { - symbol->symbolName = InitChar(strlen(name)); - SymbolUtils::StrCpy(symbol->symbolName, strlen(name), name); + symbol->symbolName = GetCharFromStr(name); free(name); name = nullptr; return; } - symbol->symbolName = InitChar(symName.size()); - SymbolUtils::StrCpy(symbol->symbolName, symName.size(), symName.c_str()); + symbol->symbolName = GetCharFromStr(symName); return; } @@ -772,8 +731,7 @@ void SymbolResolve::SearchDwarfInfo(MyDwarf& myDwarf, unsigned long addr, struct } dwarfLoadHandler.releaseLock(moduleName); if (dwarfEntry.find) { - symbol->fileName = InitChar(dwarfEntry.fileName.size()); - SymbolUtils::StrCpy(symbol->fileName, dwarfEntry.fileName.size(), dwarfEntry.fileName.c_str()); + symbol->fileName = GetCharFromStr(dwarfEntry.fileName); symbol->lineNum = dwarfEntry.lineNum; } } @@ -858,6 +816,15 @@ struct Symbol* SymbolResolve::MapKernelAddr(unsigned long addr) return nullptr; } +char* SymbolResolve::GetCharFromStr(const std::string& str) +{ + if (strToCharMap.find(str) == strToCharMap.end()) { + char* data = strdup(str.c_str()); + strToCharMap[str] = data; + } + return strToCharMap[str]; +} + struct Symbol* SymbolResolve::MapUserAddr(int pid, unsigned long addr) { if (this->moduleMap.find(pid) == this->moduleMap.end()) { @@ -882,13 +849,17 @@ struct Symbol* SymbolResolve::MapUserAddr(int pid, unsigned long addr) return it->second; } struct Symbol* symbol = InitializeSymbol(addr); - symbol->module = InitChar(module->moduleName.size()); - SymbolUtils::StrCpy(symbol->module, module->moduleName.size(), module->moduleName.c_str()); + symbol->module = GetCharFromStr(module->moduleName); unsigned long addrToSearch = addr; - if (this->elfMap.find(module->moduleName) != this->elfMap.end()) { + std::string moduleName = module->moduleName; + if (!module->mntPoint.empty()) { + symbol->mntPoint = GetCharFromStr(module->mntPoint); + moduleName = module->mntPoint + "/" + module->moduleName; + } + if (this->elfMap.find(moduleName) != this->elfMap.end()) { // If the largest symbol in the elf symbol table is detected to be smaller than the searched symbol, subtraction // is performed. - MyElf& myElf = this->elfMap.at(module->moduleName); + MyElf& myElf = this->elfMap.at(moduleName); // if the file is not exectable, subtraction is required if(!myElf.IsExecFile()){ addrToSearch = addrToSearch - module->start; @@ -896,8 +867,8 @@ struct Symbol* SymbolResolve::MapUserAddr(int pid, unsigned long addr) this->SearchElfInfo(myElf, addrToSearch, symbol, &symbol->offset); } - if (this->dwarfMap.find(module->moduleName) != this->dwarfMap.end()) { - this->SearchDwarfInfo(this->dwarfMap.at(module->moduleName), addrToSearch, symbol); + if (this->dwarfMap.find(moduleName) != this->dwarfMap.end()) { + this->SearchDwarfInfo(this->dwarfMap.at(moduleName), addrToSearch, symbol); } symbol->codeMapAddr = addrToSearch; this->symbolMap.at(pid).insert({addr, symbol}); @@ -950,17 +921,12 @@ int SymbolResolve::RecordKernel() if (sscanf(line, "%llx %c %s%*[^\n]\n", &addr, &mode, name) == EOF) { continue; } - ssize_t nameLen = strlen(name); std::shared_ptr data = std::make_shared(); - data->symbolName = InitChar(nameLen); - strcpy(data->symbolName, name); - data->mangleName = InitChar(nameLen); - strcpy(data->mangleName, name); + data->symbolName = GetCharFromStr(name); + data->mangleName = GetCharFromStr(name); data->addr = addr; - data->fileName = InitChar(KERNEL_NAME_LEN); - strcpy(data->fileName, "[kernel]"); - data->module = InitChar(KERNEL_NAME_LEN); - strcpy(data->module, "[kernel]"); + data->fileName = KERNEL; + data->module = KERNEL; data->lineNum = 0; this->ksymArray.emplace_back(data); } @@ -978,15 +944,21 @@ int SymbolResolve::UpdateModule(int pid, const char* moduleName, unsigned long s } SetFalse(this->isCleared); std::shared_ptr data = std::make_shared(); + std::string mntPoint = GetMntPoint(pid); data->moduleName = moduleName; data->start = startAddr; - int ret = this->RecordElf(data->moduleName.c_str()); + std::string recordModule = std::string{moduleName}; + if (!mntPoint.empty()) { + data->mntPoint = mntPoint; + recordModule = mntPoint + "/" + recordModule; + } + int ret = this->RecordElf(recordModule.c_str()); if (ret == LIBSYM_ERR_OPEN_FILE_FAILED || ret == LIBSYM_ERR_FILE_NOT_RGE) { return ret; } if (recordModuleType != RecordModuleType::RECORD_NO_DWARF) { - ret = this->RecordDwarf(data->moduleName.c_str()); + ret = this->RecordDwarf(recordModule.c_str()); if (ret == LIBSYM_ERR_OPEN_FILE_FAILED || ret == LIBSYM_ERR_FILE_NOT_RGE) { return ret; } @@ -1025,8 +997,7 @@ struct Symbol* SymbolResolve::MapUserCodeAddr(const std::string& moduleName, uns struct Symbol* symbol = InitializeSymbol(startAddr); unsigned long addrToSearch = startAddr; symbol->codeMapAddr = addrToSearch; - symbol->module = InitChar(moduleName.size()); - SymbolUtils::StrCpy(symbol->module, moduleName.size(), moduleName.c_str()); + symbol->module = GetCharFromStr(moduleName); if (this->elfMap.find(moduleName) != this->elfMap.end()) { this->SearchElfInfo(this->elfMap.at(moduleName), addrToSearch, symbol, &symbol->offset); } diff --git a/symbol/symbol_resolve.h b/symbol/symbol_resolve.h index 18b6c30..da42ea6 100644 --- a/symbol/symbol_resolve.h +++ b/symbol/symbol_resolve.h @@ -35,13 +35,14 @@ namespace KUNPENG_SYM { unsigned long start; unsigned long end; std::string moduleName; - } __attribute__((aligned(8))); + std::string mntPoint; + }; struct ElfMap { unsigned long start; unsigned long end; std::string symbolName; - } __attribute__((aligned(8))); + }; struct DwarfEntry { unsigned int lineNum = 0; @@ -175,6 +176,7 @@ namespace KUNPENG_SYM { private: void SearchElfInfo(MyElf &myElf, unsigned long addr, struct Symbol *symbol, unsigned long *offset); void SearchDwarfInfo(MyDwarf &myDwarf, unsigned long addr, struct Symbol *symbol); + char* GetCharFromStr(const std::string& str); struct Symbol* MapKernelAddr(unsigned long addr); struct Symbol* MapUserAddr(int pid, unsigned long addr); struct Symbol* MapUserCodeAddr(const std::string& moduleName, unsigned long addr); @@ -183,6 +185,7 @@ namespace KUNPENG_SYM { std::vector> FindDiffMaps(const std::vector>& oldMaps, const std::vector>& newMaps) const; + std::map strToCharMap; SYMBOL_MAP symbolMap{}; SYMBOL_UNMAP symbolUnmap{}; STACK_MAP stackMap{}; diff --git a/util/common.cpp b/util/common.cpp index f24e528..06ffda2 100644 --- a/util/common.cpp +++ b/util/common.cpp @@ -25,11 +25,15 @@ #include #include #include +#include #include #include "pcerrc.h" #include "pcerr.h" #include "common.h" +const std::string CUR_NS_PATH = "/proc/self/ns/mnt"; +const std::string MOUNT_INFO_PATH = "/proc/self/mountinfo"; + std::string GetRealPath(const std::string filePath) { char resolvedPath[PATH_MAX]; @@ -212,3 +216,77 @@ bool CheckCurKernelConfig(const std::string& configName) } return false; } + +struct MountEntry { + int mountId; + int parentId; + char device[32]; + char root[256]; + char mountPoint[256]; + char options[256]; + char optionFields[256]; + char fsType[32]; + char source[256]; + char superOptions[256]; +}; + +void ParseMountInfo(const std::string& mntPath, std::map& overlayMap) +{ + std::ifstream file(mntPath); + if (!file.is_open()) { + return; + } + std::string line; + while (std::getline(file, line)){ + struct MountEntry entry; + int parseLen = sscanf(line.c_str(), "%d %d %31s %255s %255s %255s %255[^-] - %31s %255s %255s", + &entry.mountId, &entry.parentId, entry.device, entry.root, entry.mountPoint, entry.options, entry.optionFields, entry.fsType, entry.source, entry.superOptions); + if (parseLen != 10) { + continue; + } + if (strcmp(entry.fsType, "overlay") == 0) { + overlayMap[entry.superOptions] = entry; + } + } +} + +bool CheckIsSameMnt(int pid) +{ + std::string newMnt = "/proc/" + std::to_string(pid) + "/ns/mnt"; + struct stat curStat; + struct stat newStat; + if (stat(CUR_NS_PATH.c_str(), &curStat) < 0) { + return true; + } + + if (stat(newMnt.c_str(), &newStat) < 0) { + return true; + } + + return curStat.st_ino == newStat.st_ino; +} + +std::string GetMntPoint(int pid) +{ + std::string mntPoint; + if (CheckIsSameMnt(pid)) { + return mntPoint; + } + std::map overlayMap; + std::map newOverlayMap; + ParseMountInfo(MOUNT_INFO_PATH, overlayMap); + std::string newMntInfo = "/proc/" + std::to_string(pid) + "/mountinfo"; + ParseMountInfo(newMntInfo, newOverlayMap); + for (const auto& item : newOverlayMap) { + if (overlayMap.find(item.first) != overlayMap.end()) { + auto entry = overlayMap[item.first]; + if (strcmp(entry.device, item.second.device) == 0) { + mntPoint = entry.mountPoint; + } + } + } + return mntPoint; +} + + + diff --git a/util/common.h b/util/common.h index 4f9a8ea..127bcf1 100644 --- a/util/common.h +++ b/util/common.h @@ -58,5 +58,5 @@ bool ConvertStrToInt(const std::string& intValStr, int32_t& val); int GetParanoidVal(); std::string GetCgroupPath(const std::string& cgroupName); bool CheckCurKernelConfig(const std::string& configName); - +std::string GetMntPoint(int pid); #endif // LIBKPROF_COMMON_H -- Gitee