diff --git a/go/src/libkperf/sym/sym.go b/go/src/libkperf/sym/sym.go index 0e8326856e9ae7e1f08053b08d4bf2e125d98a61..ee0ddd1625e55bd4a1679fe357350808f5ac99e6 100644 --- a/go/src/libkperf/sym/sym.go +++ b/go/src/libkperf/sym/sym.go @@ -92,8 +92,8 @@ func RecordModuleNoDwarf(pid int) error { } // Incremental update modules of pid, i.e. record newly loaded dynamic libraries by pid. -func IncrUpdateModule(pid int) error { - res := C.SymResolverIncrUpdateModule(C.int(pid)) +func IncrUpdateModule(pid int, ts uint64) error { + res := C.SymResolverIncrUpdateModule(C.int(pid), C.ulong(ts)) if int(res) != 0 { return errors.New(C.GoString(C.Perror())) } @@ -101,8 +101,8 @@ func IncrUpdateModule(pid int) error { } // incremental update modules of pid, i.e. record newly loaded dynamic libraries with no dwarf by pid. -func IncrUpdateModuleNoDwarf(pid int) error { - res := C.SymResolverIncrUpdateModuleNoDwarf(C.int(pid)) +func IncrUpdateModuleNoDwarf(pid int, ts uint64) error { + res := C.SymResolverIncrUpdateModuleNoDwarf(C.int(pid), C.ulong(ts)) if int(res) != 0 { return errors.New(C.GoString(C.Perror())) } diff --git a/pmu/bpf/evt_list_bpf.h b/pmu/bpf/evt_list_bpf.h index 00afaad932874105fccb016eec013660b97e35db..333f6c278cdf2d8e1432659bbbd41985b13e3f9f 100644 --- a/pmu/bpf/evt_list_bpf.h +++ b/pmu/bpf/evt_list_bpf.h @@ -49,6 +49,7 @@ public: void SetGroupInfo(const EventGroupInfo &grpInfo) override {}; void AddNewProcess(pid_t pid, const bool groupEnable, const std::shared_ptr evtLeader) override {}; + void AddNewComm(pid_t pid, unsigned long ts, char* comm) override {}; private: std::vector> cpuCounterArray; diff --git a/pmu/dummy_event.cpp b/pmu/dummy_event.cpp index 9137db89afa8c9af634139b94b5da5c2b357be97..e75671001097dde300f95bf4965128c70448ad9d 100644 --- a/pmu/dummy_event.cpp +++ b/pmu/dummy_event.cpp @@ -37,6 +37,13 @@ namespace KUNPENG_PMU { close(it->second.first); munmap(it->second.second, MAP_LEN); } + + for(auto& comm : commExecList) { + free(comm); + } + + hasDataCond.notify_all(); + if (consumeThread.joinable()) { consumeThread.join(); } @@ -60,8 +67,60 @@ namespace KUNPENG_PMU { } } + void DummyEvent::ConsumeForkQueue() { + std::unique_lock lg(dummyMutex); + if (forkPidQueue.empty()) { + hasDataCond.wait(lg); + } + auto &pid = forkPidQueue.front(); + for (const auto &evtList : evtLists) { + auto groupId = evtList->GetGroupId(); + auto evtGroupInfo = GetEvtGroupState(groupId, evtList, eventGroupInfoMap); + DummyContext ctx = {evtList, static_cast(pid), evtGroupInfo.first, evtGroupInfo.second}; + forkStrategy.DoHandler(ctx, evtGroupInfo.first, evtGroupInfo.second); + } + forkPidQueue.pop(); + } + + void DummyEvent::ConsumeCommQueue() { + std::unique_lock lg(dummyMutex); + if (commQueue.empty()) { + hasDataCond.wait(lg); + } + auto &perfRecordComm = commQueue.front(); + + char* comm = static_cast(malloc(strlen(perfRecordComm->comm) + 1)); + if (comm == nullptr) { + return; + } + strcpy(comm, perfRecordComm->comm); + commExecList.push_back(comm); + for (const auto& evtList : evtLists) { + evtList->AddNewComm(perfRecordComm->pid, perfRecordComm->sampleId.time, perfRecordComm->comm); + } + if(symMode == SymbolMode::RESOLVE_ELF) { + SymResolverIncrUpdateModuleNoDwarf(perfRecordComm->pid, perfRecordComm->sampleId.time); + } else { + SymResolverIncrUpdateModule(perfRecordComm->pid, perfRecordComm->sampleId.time); + } + commQueue.pop(); + } + void DummyEvent::ObserverForkThread() { + + consumeThread = std::thread([this]() { + while (dummyFlag) { + if (collectType == COUNTING) { + ConsumeForkQueue(); + } + + if (collectType == SAMPLING) { + ConsumeCommQueue(); + } + } + }); + dummyThread = std::thread([this]() { for (const auto& pid: ppids) { this->InitDummy(pid); @@ -70,23 +129,6 @@ namespace KUNPENG_PMU { this->HandleDummyData(); } }); - - consumeThread = std::thread([this]() { - while (dummyFlag) { - if (forkPidQueue.empty()) { - continue; - } - std::lock_guard lg(dummyMutex); - auto& pid = forkPidQueue.front(); - for (const auto& evtList: evtLists) { - auto groupId = evtList->GetGroupId(); - auto evtGroupInfo = GetEvtGroupState(groupId, evtList, eventGroupInfoMap); - DummyContext ctx = {evtList, static_cast(pid), evtGroupInfo.first, evtGroupInfo.second}; - forkStrategy.DoHandler(ctx, evtGroupInfo.first, evtGroupInfo.second); - } - forkPidQueue.pop(); - } - }); } void DummyEvent::InitDummy(pid_t pid) @@ -98,11 +140,12 @@ namespace KUNPENG_PMU { attr.exclude_kernel = 1; attr.disabled = 1; attr.sample_period = 1; - attr.sample_type = PERF_SAMPLE_TIME; + attr.sample_type = collectType == SAMPLING ? PERF_SAMPLE_TIME | PERF_SAMPLE_TID : PERF_SAMPLE_TIME; attr.sample_id_all = 1; attr.read_format = PERF_FORMAT_ID; attr.task = 1; attr.exclude_guest = 1; + attr.comm = collectType == SAMPLING ? 1 : 0; auto fd = PerfEventOpen(&attr, pid, -1, -1, 0); if (fd == -1) { ERR_PRINT("Failed open dummy event fd because of %s\n", strerror(errno)); @@ -143,19 +186,28 @@ namespace KUNPENG_PMU { while (dataTail < dataHead) { uint64_t off = dataTail % mapPage->data_size; auto* header = (struct perf_event_header*) (ringBuf + off); - if (header->type == PERF_RECORD_FORK) { - auto sample = (KUNPENG_PMU::PerfRecordFork*) header; - std::lock_guard lg(dummyMutex); - if((uint8_t*)page + MAP_LEN > ringBuf + off + sizeof(KUNPENG_PMU::PerfRecordFork)) { + + if (header->type == PERF_RECORD_FORK && collectType == COUNTING) { + auto sample = (KUNPENG_PMU::PerfRecordFork *)header; + std::unique_lock lg(dummyMutex); + if ((uint8_t *)page + MAP_LEN > ringBuf + off + sizeof(KUNPENG_PMU::PerfRecordFork)) { forkPidQueue.push(sample->tid); + hasDataCond.notify_all(); } - } - if (header->type == PERF_RECORD_EXIT) { - auto sample = (KUNPENG_PMU::PerfRecordFork*) header; + } else if (header->type == PERF_RECORD_EXIT && collectType == COUNTING) { + auto sample = (KUNPENG_PMU::PerfRecordFork *)header; if (sample->pid == sample->tid && sample->pid == pid) { exitPids.push_back(pid); } + } else if (header->type == PERF_RECORD_COMM && collectType == SAMPLING) { + std::unique_lock lg(dummyMutex); + auto sample = (KUNPENG_PMU::PerfRecordComm *)header; + if (sample->tid == sample->pid && sample->pid == pid) { + commQueue.push(sample); + hasDataCond.notify_all(); + } } + dataTail += header->size; } mapPage->data_tail = mapPage->data_head; diff --git a/pmu/dummy_event.h b/pmu/dummy_event.h index dc25970c37ea255644e1790d94a279d7c0313e16..5fb0e789b4bb8226c346916ecb21c08846014def 100644 --- a/pmu/dummy_event.h +++ b/pmu/dummy_event.h @@ -19,6 +19,7 @@ #include #include #include +#include #include "pcerr.h" #include "evt_list.h" @@ -46,11 +47,13 @@ namespace KUNPENG_PMU { class DummyEvent { public: - DummyEvent(std::vector>& evtLists, std::vector& ppids, groupMapPtr& eventGroupInfoMap) : + DummyEvent(std::vector>& evtLists, std::vector& ppids, groupMapPtr& eventGroupInfoMap, int collectType, SymbolMode symMode) : evtLists(evtLists), ppids(ppids), eventGroupInfoMap(eventGroupInfoMap), - dummyFlag(true) {}; + dummyFlag(true), + collectType(collectType), + symMode(symMode) {}; ~DummyEvent(); @@ -64,6 +67,8 @@ namespace KUNPENG_PMU { private: std::thread dummyThread; std::thread consumeThread; + int collectType; + SymbolMode symMode; volatile std::atomic dummyFlag; @@ -75,8 +80,13 @@ namespace KUNPENG_PMU { std::mutex dummyMutex; std::queue forkPidQueue; + std::queue commQueue; std::vector childThreads; + std::vector commExecList; + std::condition_variable hasDataCond; + void ConsumeForkQueue(); + void ConsumeCommQueue(); void InitDummy(pid_t pid); void ParseDummyData(void* page, pid_t pid); void HandleDummyData(); diff --git a/pmu/evt_list.h b/pmu/evt_list.h index 4fb9de3d2b5e2b80f1e8387923dd38d8d376da9d..5bb0be7dec090077b115c809225aac4d698e1c8f 100644 --- a/pmu/evt_list.h +++ b/pmu/evt_list.h @@ -110,9 +110,11 @@ public: virtual void SetGroupInfo(const EventGroupInfo &grpInfo) = 0; virtual void AddNewProcess(pid_t pid, const bool groupEnable, const std::shared_ptr evtLeader) = 0; + virtual void AddNewComm(pid_t pid, unsigned long ts, char* comm) = 0; protected: using PerfEvtPtr = std::shared_ptr; + using TsOfComm = std::pair; std::vector cpuList; std::vector pidList; std::vector unUsedPidList; @@ -130,6 +132,7 @@ protected: int prevStat; int evtStat; std::mutex mutex; + std::map> commExecList; int CollectorDoTask(PerfEvtPtr collector, int task) { diff --git a/pmu/evt_list_default.cpp b/pmu/evt_list_default.cpp index 6f96e88c2965ae7669537835a3c3a14cb05b8f83..627e566a05c2d5f852977abd58bc6db0d0ecc3ea 100644 --- a/pmu/evt_list_default.cpp +++ b/pmu/evt_list_default.cpp @@ -180,7 +180,17 @@ void KUNPENG_PMU::EvtListDefault::FillFields( } data[i].groupId = this->groupId; if (data[i].comm == nullptr) { - data[i].comm = procTopo->comm; + char* comm = procTopo->comm; + if (!commExecList[data[i].pid].empty()) { + auto commVec = commExecList[data[i].pid]; + for (const auto& item : commVec) { + if (data[i].ts < item.first) { + break; + } + comm = item.second; + } + } + data[i].comm = comm; } if (data[i].ts == 0) { data[i].ts = this->ts; @@ -317,6 +327,10 @@ void KUNPENG_PMU::EvtListDefault::AddNewProcess(pid_t pid, const bool groupEnabl } } +void KUNPENG_PMU::EvtListDefault::AddNewComm(pid_t pid, unsigned long ts, char* comm) { + commExecList[pid].emplace_back(ts, comm); +} + void KUNPENG_PMU::EvtListDefault::ClearExitFd() { if (this->pidList.size() == 1 && this->pidList[0]->tid == -1) { diff --git a/pmu/evt_list_default.h b/pmu/evt_list_default.h index bc4d5d21ac1fcce108fc8ecfa308149e6b12dfa9..bc63fb6fa443287026d766aee9c35f39d97bf132 100644 --- a/pmu/evt_list_default.h +++ b/pmu/evt_list_default.h @@ -47,6 +47,8 @@ public: void SetGroupInfo(const EventGroupInfo &grpInfo) override; void AddNewProcess(pid_t pid, const bool groupEnable, const std::shared_ptr evtLeader) override; + void AddNewComm(pid_t pid, unsigned long ts, char* comm) override; + void ClearExitFd(); private: int CollectorXYArrayDoTask(std::vector>& xyArray, int task); diff --git a/pmu/pmu_event.h b/pmu/pmu_event.h index d8cdd63549df409dedb8b525f9c94ee5dc2559f9..2a8826c1faaae8957525d134c9b7fd03e7d3a840 100644 --- a/pmu/pmu_event.h +++ b/pmu/pmu_event.h @@ -146,6 +146,7 @@ struct PerfRecordComm { struct perf_event_header header; __u32 pid, tid; char comm[16]; + struct sampleId sampleId; }; struct PerfRecordSample { diff --git a/pmu/pmu_list.cpp b/pmu/pmu_list.cpp index 47ef6e17f6631da2f6ddce9d8b666e0a5483f6da..a40b6c245394b9132682719d106283129ebfb0f6 100644 --- a/pmu/pmu_list.cpp +++ b/pmu/pmu_list.cpp @@ -629,7 +629,7 @@ namespace KUNPENG_PMU { } if (pmuData.stack == nullptr) { - pmuData.stack = StackToHash(pmuData.pid, ipsData.ips.data(), ipsData.ips.size()); + pmuData.stack = StackToHashWithTime(pmuData.pid, ipsData.ips.data(), ipsData.ips.size(), pmuData.ts); } } //Exceptions generated by the symbol interface are not directly exposed and are processed as warnings. @@ -1025,13 +1025,10 @@ namespace KUNPENG_PMU { if (!taskParam->pmuEvt->includeNewFork) { return; } - if (taskParam->pmuEvt->collectType != COUNTING) { - return; - } if (taskParam->pidList.empty()) { return; } - auto* dummyEvent = new DummyEvent(GetEvtList(pd), ppidList.at(pd), GetDataEvtGroupList(pd)); + auto* dummyEvent = new DummyEvent(GetEvtList(pd), ppidList.at(pd), GetDataEvtGroupList(pd), taskParam->pmuEvt->collectType, symModeList[pd]); dummyEvent->ObserverForkThread(); dummyList[pd] = dummyEvent; } diff --git a/symbol/symbol.cpp b/symbol/symbol.cpp index 938ee6ff6ec987c956b6ed90e3ca8c7409fbec13..1f3a140098a5c7384408878bbbbe6ecf75491f2d 100644 --- a/symbol/symbol.cpp +++ b/symbol/symbol.cpp @@ -82,7 +82,17 @@ void SymResolverDestroy() struct Stack* StackToHash(int pid, unsigned long* stack, int nr) { try { - return SymbolResolve::GetInstance()->StackToHash(pid, stack, nr); + return SymbolResolve::GetInstance()->StackToHash(pid, stack, nr, 0); + } catch (std::bad_alloc& err) { + pcerr::New(COMMON_ERR_NOMEM); + return nullptr; + } +} + +struct Stack* StackToHashWithTime(int pid, unsigned long* stack, int nr, unsigned long ts) +{ + try { + return SymbolResolve::GetInstance()->StackToHash(pid, stack, nr, ts); } catch (std::bad_alloc& err) { pcerr::New(COMMON_ERR_NOMEM); return nullptr; @@ -92,27 +102,27 @@ struct Stack* StackToHash(int pid, unsigned long* stack, int nr) struct Symbol* SymResolverMapAddr(int pid, unsigned long addr) { try { - return SymbolResolve::GetInstance()->MapAddr(pid, addr); + return SymbolResolve::GetInstance()->MapAddr(pid, addr, 0); } catch (std::bad_alloc& err) { pcerr::New(COMMON_ERR_NOMEM); return nullptr; } } -int SymResolverIncrUpdateModule(int pid) +int SymResolverIncrUpdateModule(int pid, unsigned long commExeTime) { try { - return SymbolResolve::GetInstance()->UpdateModule(pid, RecordModuleType::RECORD_ALL); + return SymbolResolve::GetInstance()->UpdateModule(pid, RecordModuleType::RECORD_ALL, commExeTime); } catch (std::bad_alloc& err) { pcerr::New(COMMON_ERR_NOMEM); return COMMON_ERR_NOMEM; } } -int SymResolverIncrUpdateModuleNoDwarf(int pid) +int SymResolverIncrUpdateModuleNoDwarf(int pid, unsigned long commExeTime) { try { - return SymbolResolve::GetInstance()->UpdateModule(pid, RecordModuleType::RECORD_NO_DWARF); + return SymbolResolve::GetInstance()->UpdateModule(pid, RecordModuleType::RECORD_NO_DWARF, commExeTime); } catch (std::bad_alloc& err) { pcerr::New(COMMON_ERR_NOMEM); return COMMON_ERR_NOMEM; diff --git a/symbol/symbol.h b/symbol/symbol.h index bab9951f5806256b066e8c859beb21f1db45185d..38194d0746094e7866154229e97c3d1e50b92246 100644 --- a/symbol/symbol.h +++ b/symbol/symbol.h @@ -65,12 +65,11 @@ int SymResolverRecordModuleNoDwarf(int pid); /** * Incremental update modules of pid, i.e. record newly loaded dynamic libraries by pid. */ -int SymResolverIncrUpdateModule(int pid); - +int SymResolverIncrUpdateModule(int pid, unsigned long commExeTime); /** * Incremental update modules of pid, i.e. record newly loaded dynamic libraries with no dwarf by pid. */ -int SymResolverIncrUpdateModuleNoDwarf(int pid); +int SymResolverIncrUpdateModuleNoDwarf(int pid, unsigned long commExeTime); int SymResolverUpdateModule(int pid, const char* moduleName, unsigned long startAddr); @@ -96,6 +95,11 @@ void SymResolverDestroy(); */ struct Stack* StackToHash(int pid, unsigned long* stack, int nr); +/** + * Convert a callstack to a unsigned long long hashid + */ +struct Stack* StackToHashWithTime(int pid, unsigned long* stack, int nr, unsigned long ts); + /** * Map a specific address to a symbol */ diff --git a/symbol/symbol_resolve.cpp b/symbol/symbol_resolve.cpp index 70aa079e4eddf8fd7b1f590e884d29f3ec76368e..4d9823ecd3b673dd735d84a7ae04568a2635d258 100644 --- a/symbol/symbol_resolve.cpp +++ b/symbol/symbol_resolve.cpp @@ -549,7 +549,7 @@ int SymbolResolve::RecordModule(int pid, RecordModuleType recordModuleType) return 0; } -int SymbolResolve::UpdateModule(int pid, RecordModuleType recordModuleType) +int SymbolResolve::UpdateModule(int pid, RecordModuleType recordModuleType, unsigned long commExeTime) { if (pid < 0) { pcerr::New(LIBSYM_ERR_PARAM_PID_INVALID, "libsym param process ID must be greater than 0"); @@ -576,22 +576,33 @@ int SymbolResolve::UpdateModule(int pid, RecordModuleType recordModuleType) // Find new dynamic modules. auto &oldModVec = moduleMap[pid]; - if (newModVec.size() <= oldModVec.size()) { + if (newModVec.size() <= oldModVec.size() && !commExeTime) { pcerr::New(SUCCESS); moduleSafeHandler.releaseLock(pid); return SUCCESS; } - auto diffModVec = FindDiffMaps(oldModVec, newModVec); + auto diffModVec = FindDiffMaps(oldModVec, newModVec, commExeTime); // Load modules. - for (auto& item : diffModVec) { - this->RecordElf(item->moduleName.c_str()); - if (recordModuleType != RecordModuleType::RECORD_NO_DWARF) { - this->RecordDwarf(item->moduleName.c_str()); + if (!commExeTime) { + for (auto &item : diffModVec) { + this->RecordElf(item->moduleName.c_str()); + if (recordModuleType != RecordModuleType::RECORD_NO_DWARF) { + this->RecordDwarf(item->moduleName.c_str()); + } + } + } else { + for (auto &item : newModVec) { + this->RecordElf(item->moduleName.c_str()); + if (recordModuleType != RecordModuleType::RECORD_NO_DWARF) { + this->RecordDwarf(item->moduleName.c_str()); + } } } + for (auto& mod : diffModVec) { oldModVec.emplace_back(mod); } + pcerr::New(SUCCESS); moduleSafeHandler.releaseLock(pid); return SUCCESS; @@ -804,7 +815,7 @@ std::shared_ptr SymbolResolve::AddrToModule( return nullptr; } -struct Stack* SymbolResolve::StackToHash(int pid, unsigned long* stack, int nr) +struct Stack* SymbolResolve::StackToHash(int pid, unsigned long* stack, int nr, unsigned long ts) { if (this->stackMap.find(pid) == this->stackMap.end()) { this->stackMap[pid] = {}; @@ -817,7 +828,7 @@ struct Stack* SymbolResolve::StackToHash(int pid, unsigned long* stack, int nr) struct Stack* head = nullptr; for (int i = nr - 1; i >= 0; i--) { struct Stack* current = CreateNode(); - auto symbol = this->MapAddr(pid, stack[i]); + auto symbol = this->MapAddr(pid, stack[i], ts); if (symbol != nullptr) { current->symbol = symbol; } else { @@ -858,7 +869,7 @@ struct Symbol* SymbolResolve::MapKernelAddr(unsigned long addr) return nullptr; } -struct Symbol* SymbolResolve::MapUserAddr(int pid, unsigned long addr) +struct Symbol* SymbolResolve::MapUserAddr(int pid, unsigned long addr, unsigned long ts) { if (this->moduleMap.find(pid) == this->moduleMap.end()) { pcerr::New(LIBSYM_ERR_NOT_FIND_PID, "The libsym process ID " + std::to_string(pid) + " cannot be found."); @@ -869,6 +880,17 @@ struct Symbol* SymbolResolve::MapUserAddr(int pid, unsigned long addr) if (!module) { return nullptr; } + unsigned long start = module->start; + std::string moduleName = module->moduleName; + + if (ts > 0 && sameStartModule.find(moduleName) != sameStartModule.end()) { + for (const auto& item : sameStartModule[moduleName]) { + if (ts < item.first) { + break; + } + moduleName = item.second; + } + } /** * Try to search elf data first */ @@ -882,22 +904,22 @@ 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 = InitChar(moduleName.size()); + SymbolUtils::StrCpy(symbol->module, moduleName.size(), moduleName.c_str()); unsigned long addrToSearch = addr; - if (this->elfMap.find(module->moduleName) != this->elfMap.end()) { + 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; + addrToSearch = addrToSearch - start; } 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}); @@ -905,7 +927,7 @@ struct Symbol* SymbolResolve::MapUserAddr(int pid, unsigned long addr) return symbol; } -struct Symbol* SymbolResolve::MapAddr(int pid, unsigned long addr) +struct Symbol* SymbolResolve::MapAddr(int pid, unsigned long addr, unsigned long ts) { struct Symbol* data = nullptr; if (addr > KERNEL_START_ADDR) { @@ -919,7 +941,7 @@ struct Symbol* SymbolResolve::MapAddr(int pid, unsigned long addr) } data->offset = addr - data->addr; } else { - data = this->MapUserAddr(pid, addr); + data = this->MapUserAddr(pid, addr, ts); } return data; } @@ -1201,16 +1223,22 @@ struct StackAsm* SymbolResolve::MapAsmCodeStack( std::vector> SymbolResolve::FindDiffMaps( const std::vector>& oldMaps, - const std::vector>& newMaps) const + const std::vector>& newMaps, unsigned long commExeTime) { std::vector> diffMaps; - std::set oldStarts; + std::unordered_map oldStarts; for (const auto& oldMod : oldMaps) { - oldStarts.insert(oldMod->start); + oldStarts.insert({oldMod->start, oldMod->moduleName}); } for (auto newMod : newMaps) { if (oldStarts.find(newMod->start) == oldStarts.end()) { diffMaps.emplace_back(newMod); + } else { + if (!commExeTime) { + continue; + } + auto& oldModuleStr = oldStarts[newMod->start]; + sameStartModule[oldModuleStr].emplace_back(commExeTime, newMod->moduleName); } } diff --git a/symbol/symbol_resolve.h b/symbol/symbol_resolve.h index 18b6c309a283087dad558953cd95d134f7d731cb..ffa27e57ad69765cf460971b42c28ef2490872d2 100644 --- a/symbol/symbol_resolve.h +++ b/symbol/symbol_resolve.h @@ -131,6 +131,7 @@ namespace KUNPENG_SYM { using MODULE_MAP = std::unordered_map>>; using DWARF_MAP = std::unordered_map; using ELF_MAP = std::unordered_map; + using TIME_MODULE_PAIR = std::pair; class SymbolUtils final { public: @@ -162,12 +163,12 @@ namespace KUNPENG_SYM { int RecordKernel(); int RecordElf(const char* fileName); int RecordDwarf(const char* fileName); - int UpdateModule(int pid, RecordModuleType recordModuleType); + int UpdateModule(int pid, RecordModuleType, unsigned long commExeTime); int UpdateModule(int pid, const char* moduleName, unsigned long startAddr, RecordModuleType recordModuleType); void Clear(); std::shared_ptr AddrToModule(std::vector>& processModule, unsigned long addr); - struct Stack* StackToHash(int pid, unsigned long* stack, int nr); - struct Symbol* MapAddr(int pid, unsigned long addr); + struct Stack* StackToHash(int pid, unsigned long* stack, int nr, unsigned long ts); + struct Symbol* MapAddr(int pid, unsigned long addr, unsigned long ts); struct StackAsm* MapAsmCode(const char* moduleName, unsigned long startAddr, unsigned long endAddr); struct Symbol* MapCodeAddr(const char* moduleName, unsigned long startAddr); int GetBuildId(const char *moduleName, char **buildId); @@ -176,12 +177,12 @@ namespace KUNPENG_SYM { void SearchElfInfo(MyElf &myElf, unsigned long addr, struct Symbol *symbol, unsigned long *offset); void SearchDwarfInfo(MyDwarf &myDwarf, unsigned long addr, struct Symbol *symbol); struct Symbol* MapKernelAddr(unsigned long addr); - struct Symbol* MapUserAddr(int pid, unsigned long addr); + struct Symbol* MapUserAddr(int pid, unsigned long addr, unsigned long ts); struct Symbol* MapUserCodeAddr(const std::string& moduleName, unsigned long addr); struct Symbol* MapCodeElfAddr(const std::string& moduleName, unsigned long addr); struct StackAsm* MapAsmCodeStack(const std::string& moduleName, unsigned long startAddr, unsigned long endAddr); std::vector> FindDiffMaps(const std::vector>& oldMaps, - const std::vector>& newMaps) const; + const std::vector>& newMaps, unsigned long commExeTime); SYMBOL_MAP symbolMap{}; SYMBOL_UNMAP symbolUnmap{}; @@ -191,6 +192,7 @@ namespace KUNPENG_SYM { ELF_MAP elfMap{}; bool isCleared = false; std::vector> ksymArray; + std::unordered_map> sameStartModule; SymbolResolve() {}