From bdfc02f31df80bebb8b5d7a091157c8f9b553100 Mon Sep 17 00:00:00 2001 From: "lijindong (C)" <2220386943@qq.com> Date: Tue, 9 Jul 2024 14:39:20 +0800 Subject: [PATCH] add the demangle mode --- include/pmu.h | 7 ++++ pmu/pmu.cpp | 1 + pmu/pmu_list.cpp | 15 ++++++++ pmu/pmu_list.h | 4 +++ symbol/symbol.cpp | 4 +++ symbol/symbol.h | 10 ++++++ symbol/symbol_resolve.cpp | 18 ++++++---- symbol/symbol_resolve.h | 3 ++ test/test_symbol/test_libsym.cpp | 23 +++++++++--- util/thread_local.h | 61 ++++++++++++++++++++++++++++++++ 10 files changed, 135 insertions(+), 11 deletions(-) create mode 100644 util/thread_local.h diff --git a/include/pmu.h b/include/pmu.h index 98fd691..e2f553f 100644 --- a/include/pmu.h +++ b/include/pmu.h @@ -64,6 +64,11 @@ enum SymbolMode { RESOLVE_ELF_DWARF = 2 }; +enum SymMangleMode { + NEED_MANGLE = 0, // need mangle symbol. + NEED_DEMANGLE = 1 // need demangle symbol, default is demangle symbol. +}; + struct PmuAttr { // Event list. // Refer 'perf list' for details about event names. @@ -108,6 +113,8 @@ struct PmuAttr { // This indicates how to analyze symbols of samples. // Refer to comments of SymbolMode. enum SymbolMode symbolMode; + // Refer to comments of SymMangleMode. + enum SymMangleMode symMangleMode; // This indicates whether to collect whole callchains or only top frame. unsigned callStack : 1; diff --git a/pmu/pmu.cpp b/pmu/pmu.cpp index d7b58e7..7909ef4 100644 --- a/pmu/pmu.cpp +++ b/pmu/pmu.cpp @@ -277,6 +277,7 @@ int PmuOpen(enum PmuTaskType collectType, struct PmuAttr *attr) } KUNPENG_PMU::PmuList::GetInstance()->SetSymbolMode(pd, attr->symbolMode); + KUNPENG_PMU::PmuList::GetInstance()->SetMangleMode(pd, attr->symMangleMode); err = KUNPENG_PMU::PmuList::GetInstance()->Register(pd, taskAttr.get()); if (err != SUCCESS) { PmuList::GetInstance()->Close(pd); diff --git a/pmu/pmu_list.cpp b/pmu/pmu_list.cpp index f81686c..470b48a 100644 --- a/pmu/pmu_list.cpp +++ b/pmu/pmu_list.cpp @@ -369,6 +369,9 @@ namespace KUNPENG_PMU { continue; } if (pmuData.stack == nullptr) { + SymVariables symVariables; + symVariables.mangleMode = symMangleList[eventData.pd]; + AdaptVariables(symVariables); pmuData.stack = StackToHash(pmuData.pid, ipsData.ips.data(), ipsData.ips.size()); } } @@ -659,9 +662,21 @@ namespace KUNPENG_PMU { symModeList[pd] = mode; } + void PmuList::SetMangleMode(const int pd, const SymMangleMode &mode) + { + lock_guard lg(dataListMtx); + symMangleList[pd] = mode; + } + SymbolMode PmuList::GetSymbolMode(const unsigned pd) { lock_guard lg(dataListMtx); return symModeList[pd]; } + + SymMangleMode PmuList::GetMangleMode(const unsigned pd) + { + lock_guard lg(dataListMtx); + return symMangleList[pd]; + } } \ No newline at end of file diff --git a/pmu/pmu_list.h b/pmu/pmu_list.h index 699261a..013a04b 100644 --- a/pmu/pmu_list.h +++ b/pmu/pmu_list.h @@ -63,6 +63,7 @@ public: void FreeData(PmuData* pmuData); int GetTaskType(const int pd) const; void SetSymbolMode(const int pd, const SymbolMode &mode); + void SetMangleMode(const int pd, const SymMangleMode &mode); int NewPd(); @@ -116,6 +117,8 @@ private: void AggregateUncoreData(const unsigned pd, const std::vector &evData, std::vector &newEvData); std::vector& GetPreviousData(const unsigned pd); SymbolMode GetSymbolMode(const unsigned pd); + SymMangleMode GetMangleMode(const unsigned pd); + static std::mutex pmuListMtx; static std::mutex dataListMtx; @@ -151,6 +154,7 @@ private: unsigned maxPd = 0; std::unordered_map symModeList; + std::unordered_map symMangleList; }; } // namespace KUNPENG_PMU #endif diff --git a/symbol/symbol.cpp b/symbol/symbol.cpp index 699dca8..7f35bed 100644 --- a/symbol/symbol.cpp +++ b/symbol/symbol.cpp @@ -153,3 +153,7 @@ void FreeAsmStack(struct StackAsm* stackAsm) { SymbolUtils::FreeStackAsm(&stackAsm); } + +void AdaptVariables(struct SymVariables var) { + SymbolResolve::GetInstance()->SetVariables(var); +} diff --git a/symbol/symbol.h b/symbol/symbol.h index aadd51d..48f7820 100644 --- a/symbol/symbol.h +++ b/symbol/symbol.h @@ -54,6 +54,10 @@ struct AsmCode { unsigned int lineNum; // the real line of this addr }; +struct SymVariables { + int mangleMode; // default mangle mode,will give demangle symbol. +}; + void SymResolverInit(); int SymResolverRecordKernel(); @@ -119,6 +123,12 @@ void FreeModuleData(int pid); */ void FreeAsmStack(struct StackAsm* stackAsm); +/** + * change the variables, influence some output data. + * mangleMode, if the mode is 1, the symbol will demangle. + */ +void AdaptVariables(struct SymVariables var); + struct ProcTopology { int pid; int tid; diff --git a/symbol/symbol_resolve.cpp b/symbol/symbol_resolve.cpp index e22d0e3..1c35af9 100644 --- a/symbol/symbol_resolve.cpp +++ b/symbol/symbol_resolve.cpp @@ -754,12 +754,14 @@ 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(); - char *name = CppNamedDemangle(symName.c_str()); - if (name) { - SymbolUtils::StrCpy(symbol->symbolName, MAX_LINUX_SYMBOL_LEN, name); - free(name); - name = nullptr; - return; + if (demangleLocal.Get()) { + char *name = CppNamedDemangle(symName.c_str()); + if (name) { + SymbolUtils::StrCpy(symbol->symbolName, MAX_LINUX_SYMBOL_LEN, name); + free(name); + name = nullptr; + return; + } } SymbolUtils::StrCpy(symbol->symbolName, MAX_LINUX_SYMBOL_LEN, symName.c_str()); return; @@ -1166,6 +1168,10 @@ std::vector> SymbolResolve::FindDiffMaps( return diffMaps; } +void SymbolResolve::SetVariables(struct SymVariables symVariables) { + this->demangleLocal.Set(symVariables.mangleMode); +} + SymbolResolve* SymbolResolve::instance = nullptr; std::mutex SymbolResolve::mutex; std::mutex SymbolResolve::kernelMutex; diff --git a/symbol/symbol_resolve.h b/symbol/symbol_resolve.h index 134bbdf..2e490cb 100644 --- a/symbol/symbol_resolve.h +++ b/symbol/symbol_resolve.h @@ -26,6 +26,7 @@ #include #include #include +#include "thread_local.h" #include "safe_handler.h" #include "linked_list.h" #include "symbol.h" @@ -171,6 +172,7 @@ namespace KUNPENG_SYM { struct Symbol* MapAddr(int pid, unsigned long addr); struct StackAsm* MapAsmCode(const char* moduleName, unsigned long startAddr, unsigned long endAddr); struct Symbol* MapCodeAddr(const char* moduleName, unsigned long startAddr); + void SetVariables(struct SymVariables symVariables); private: void SearchElfInfo(MyElf &myElf, unsigned long addr, struct Symbol *symbol, unsigned long *offset); @@ -203,6 +205,7 @@ namespace KUNPENG_SYM { SafeHandler elfSafeHandler; SafeHandler symSafeHandler; SafeHandler dwarfLoadHandler; + ThreadLocal demangleLocal = {1}; static std::mutex kernelMutex; static SymbolResolve* instance; static std::mutex mutex; diff --git a/test/test_symbol/test_libsym.cpp b/test/test_symbol/test_libsym.cpp index 015ba34..fba2505 100644 --- a/test/test_symbol/test_libsym.cpp +++ b/test/test_symbol/test_libsym.cpp @@ -14,15 +14,11 @@ ******************************************************************************/ #include #include -#include #include -#include -#include #include #include #include "pcerrc.h" #include "symbol_resolve.h" -#include "linked_list.h" #include "symbol.h" /******************************************* * @brief DT testcases for libsym.so APIs * @@ -589,7 +585,6 @@ void InsertSafeDataAndDoInsert2(std::unordered_map& map, SafeHandler lock; std::unordered_map map; @@ -601,4 +596,22 @@ TEST(symbol, test_safe_handler){ b.join(); c.join(); d.join(); +} + +void SetData(const std::string &str, ThreadLocal &local) { + local.Set(str); + std::string get = local.Get(); + ASSERT_EQ(local.Get(), str); +} + +TEST(symbol, test_local_thread) { + ThreadLocal local(""); + local.Set("c"); + std::thread a(SetData, "a", std::ref(local)); + std::thread b(SetData, "b", std::ref(local)); + a.join(); + b.join(); + ASSERT_EQ(local.Get(), "c"); + local.Set("d"); + ASSERT_EQ(local.Get(), "d"); } \ No newline at end of file diff --git a/util/thread_local.h b/util/thread_local.h new file mode 100644 index 0000000..4ffeaa0 --- /dev/null +++ b/util/thread_local.h @@ -0,0 +1,61 @@ +/****************************************************************************** + * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved. + * libkperf licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v2 for more details. + * Author: Mr.Li + * Create: 2024-07-09 + * Description: used for save the local thread data. + ******************************************************************************/ + +#ifndef LIBKPROF_THREAD_LOCAL_H +#define LIBKPROF_THREAD_LOCAL_H + +#include +#include +#include +#include + +template +class ThreadLocal { +public: + ThreadLocal() = delete; + + ThreadLocal(T t) : defaultData(t) {}; + + void Set(T t) { + safeHelp.tryLock(0); + threadLocalMap[std::this_thread::get_id()] = t; + safeHelp.releaseLock(0); + } + + void Remove(T t) { + safeHelp.tryLock(0); + threadLocalMap.erase(std::this_thread::get_id()); + safeHelp.releaseLock(0); + } + + T Get() { + safeHelp.tryLock(0); + std::thread::id id = std::this_thread::get_id(); + if (threadLocalMap.find(id) == threadLocalMap.end()) { ; + safeHelp.releaseLock(0); + return defaultData; + } + safeHelp.releaseLock(0); + return threadLocalMap.at(id); + } + +private: + T defaultData; + std::map threadLocalMap; + SafeHandler safeHelp; +}; + + +#endif //LIBKPROF_THREAD_LOCAL_H -- Gitee