diff --git a/0013-restrict-function-redesign-trace-check-proc.patch b/0013-restrict-function-redesign-trace-check-proc.patch new file mode 100644 index 0000000000000000000000000000000000000000..ed9502236c087d8603fcbf7c157028dc4c7f4eee --- /dev/null +++ b/0013-restrict-function-redesign-trace-check-proc.patch @@ -0,0 +1,1133 @@ +From 96c61b8356e328fa7f44902b6760e5abfb6320c7 Mon Sep 17 00:00:00 2001 +From: LHesperus <2639350497@qq.com> +Date: Sat, 2 Dec 2023 19:42:43 +0800 +Subject: [PATCH] restrict function, redesign trace check proc + +--- + extra-tools/da-tool/analysis/config.cpp | 1 + + extra-tools/da-tool/analysis/config.h | 1 + + extra-tools/da-tool/analysis/function_stack.h | 3 +- + .../da-tool/analysis/sched_analysis.cpp | 139 +++++++---- + extra-tools/da-tool/analysis/sched_analysis.h | 34 ++- + extra-tools/da-tool/analysis/time_pair.cpp | 97 +++++--- + extra-tools/da-tool/analysis/time_pair.h | 18 +- + .../da-tool/analysis/trace_resolve.cpp | 233 ++++++++++++++---- + extra-tools/da-tool/analysis/trace_resolve.h | 50 +++- + extra-tools/da-tool/main.cpp | 1 - + extra-tools/da-tool/script/da-tool.sh | 54 ++-- + 11 files changed, 450 insertions(+), 181 deletions(-) + +diff --git a/extra-tools/da-tool/analysis/config.cpp b/extra-tools/da-tool/analysis/config.cpp +index d84cc5b..23eee95 100644 +--- a/extra-tools/da-tool/analysis/config.cpp ++++ b/extra-tools/da-tool/analysis/config.cpp +@@ -47,6 +47,7 @@ void Config::pathInit() + filename[FILE_TYPE_OUTPUT_RUN_LOG] = pathOutputDebug + "/run.log"; + filename[FILE_TYPE_DEBUG_TIME_PAIE] = pathOutputDebug + "/debug_time_pair"; + filename[FILE_TYPE_DEBUG_TRACE] = pathOutputDebug + "/debug_trace"; ++ filename[FILE_TYPE_DEBUG_TRACE_FUNCPAIRMAP] = pathOutputDebug + "/debug_trace_funcpair"; + filename[FILE_TYPE_DEBUG_FUNC_STACK_TRACE] = pathOutputDebug + "/debug_funcstk_trace"; + filename[FILE_TYPE_DEBUG_REGEX] = pathOutputDebug + "/debug_resolve_function_trace"; + filename[FILE_TYPE_DEBUG_CONFIG] = pathOutputDebug + "/debug_config_resolve"; +diff --git a/extra-tools/da-tool/analysis/config.h b/extra-tools/da-tool/analysis/config.h +index e1a5d4a..bbf339e 100644 +--- a/extra-tools/da-tool/analysis/config.h ++++ b/extra-tools/da-tool/analysis/config.h +@@ -33,6 +33,7 @@ typedef enum { + FILE_TYPE_DEBUG_CONFIG, + FILE_TYPE_DEBUG_TIME_PAIR_MARK, + // debug 2 ++ FILE_TYPE_DEBUG_TRACE_FUNCPAIRMAP, + // debug 3 + FILE_TYPE_DEBUG_TRACE, + FILE_TYPE_DEBUG_REGEX, +diff --git a/extra-tools/da-tool/analysis/function_stack.h b/extra-tools/da-tool/analysis/function_stack.h +index 9f6e2d7..1306cbc 100644 +--- a/extra-tools/da-tool/analysis/function_stack.h ++++ b/extra-tools/da-tool/analysis/function_stack.h +@@ -27,8 +27,7 @@ typedef enum { + FS_DELAY_TYPE_MAX, + } FS_DELAY_TYPE; + +-class FsDelayInfo // function stack delay info +-{ ++class FsDelayInfo { // function stack delay info + public: + std::vector delay[FS_DELAY_TYPE_MAX]; + std::vector retVal; +diff --git a/extra-tools/da-tool/analysis/sched_analysis.cpp b/extra-tools/da-tool/analysis/sched_analysis.cpp +index aea3d25..9aef4b7 100644 +--- a/extra-tools/da-tool/analysis/sched_analysis.cpp ++++ b/extra-tools/da-tool/analysis/sched_analysis.cpp +@@ -24,9 +24,9 @@ SchedAnalysis::SchedAnalysis() + + } + +-void SchedAnalysis::processSchedAnalysisLoop(const int &pid, const int ×tamp, const int &coreIndex) ++void SchedAnalysis::processSchedAnalysisLoop(const int &pid, const int ×tamp, const int &coreIndex, const bool &isRet) + { +- if (processSchedMap.count(pid) != 0) { ++ if (processSchedMap.count(pid) == 0) { + ProcessSchedInfo tmp; + processSchedMap.emplace(pid, tmp); + } +@@ -34,9 +34,16 @@ void SchedAnalysis::processSchedAnalysisLoop(const int &pid, const int ×tam + ProcessCoreTrace pct; + pct.startTime = timestamp; + pct.endTime = timestamp; +- pct.coreIndex = coreIndex; +- if (size != 0) { ++ pct.startCoreId = coreIndex; ++ pct.endCoreId = coreIndex; ++ pct.startIsRet = isRet; ++ pct.endIsRet = isRet; ++ pct.coreTraceType = CORE_TRACE_INVALID; ++ ++ if (size > 0) { + processSchedMap[pid].coreTrace[size - 1].endTime = timestamp; ++ processSchedMap[pid].coreTrace[size - 1].endCoreId = coreIndex; ++ processSchedMap[pid].coreTrace[size - 1].endIsRet = isRet; + } + processSchedMap[pid].coreTrace.emplace_back(pct); + } +@@ -65,45 +72,75 @@ void SchedAnalysis::schedInfoProc() + + if (functionIndex == sched_switch_funcidx) { + int nextPid = line_info_tmp.schedSwitchLine.nextPid; +- processSchedAnalysisLoop(pid, timestamp, -1); // pid1 - > pidn +- processSchedAnalysisLoop(nextPid, timestamp, coreIndex); // pidm - > pid1 ++ processSchedAnalysisLoop(pid, timestamp, coreIndex, false); // pid1 - > pidn ++ processSchedAnalysisLoop(nextPid, timestamp, coreIndex, true); // pidm - > pid1 ++ } ++ } ++ // last coreTrace always invalid ++ for (auto &sched_tmp : processSchedMap) { ++ if (!sched_tmp.second.coreTrace.empty()) { ++ sched_tmp.second.coreTrace.pop_back(); + } + } + } + +-void SchedAnalysis::schedInfoAnalysis() ++void SchedAnalysis::schedInfoVaildMark() + { + for (auto &sched_tmp : processSchedMap) { +- int lastCoreIndex = -1; +- int delaySum = 0; +- int delaySched = 0; +- int schedSwitchTimes = 0; +- int cpuSwitchTimes = 0; + for (auto &coreTrace : sched_tmp.second.coreTrace) { +- int delay = coreTrace.endTime - coreTrace.startTime; +- int coreIndex = coreTrace.coreIndex; +- delaySum += delay; +- if (coreIndex == -1) { +- delaySched += delay; +- schedSwitchTimes++; +- } else { +- sched_tmp.second.runTimeOfCore[coreIndex] += delay; ++ if (!coreTrace.startIsRet && coreTrace.endIsRet) { ++ coreTrace.coreTraceType = CORE_TRACE_SCHEDULING; + } + +- if (lastCoreIndex == -1 && coreIndex != -1) { +- lastCoreIndex = coreIndex; ++ if (coreTrace.startIsRet && !coreTrace.endIsRet && (coreTrace.startCoreId == coreTrace.endCoreId)) { ++ coreTrace.coreTraceType = CORE_TRACE_ONCORE; ++ } ++ } ++ } ++} ++ ++ ++void SchedAnalysis::schedInfoAnalysis() ++{ ++ for (auto &sched_tmp : processSchedMap) { ++ int delaySum[SCHED_SUMMARY_MAX] = { 0 }; ++ int schedSwitchTimes[SCHED_SUMMARY_MAX] = { 0 }; ++ int cpuSwitchTimes[SCHED_SUMMARY_MAX] = { 0 }; ++ int vaildDelaySched = 0; // Invalid scheduling cannot be analyzed ++ for (const auto &coreTrace : sched_tmp.second.coreTrace) { ++ int delay = coreTrace.endTime - coreTrace.startTime; ++ delaySum[SCHED_SUMMARY_ALL] += delay; ++ if (!coreTrace.startIsRet) { // count pid1->pidn times ++ schedSwitchTimes[SCHED_SUMMARY_ALL]++; ++ } ++ if (coreTrace.startCoreId != coreTrace.endCoreId) { ++ cpuSwitchTimes[SCHED_SUMMARY_ALL]++; ++ } ++ if (coreTrace.coreTraceType != CORE_TRACE_INVALID) { ++ delaySum[SCHED_SUMMARY_VAILD] += delay; ++ } ++ if (coreTrace.coreTraceType == CORE_TRACE_ONCORE) { ++ int coreIndex = coreTrace.startCoreId; ++ sched_tmp.second.runTimeOfCore[coreIndex] += delay; + } + +- if (lastCoreIndex != coreIndex && coreIndex != -1) { +- cpuSwitchTimes++; +- lastCoreIndex = coreTrace.coreIndex; ++ if (coreTrace.coreTraceType == CORE_TRACE_SCHEDULING) { ++ vaildDelaySched += delay; ++ schedSwitchTimes[SCHED_SUMMARY_VAILD]++; ++ if (coreTrace.startCoreId != coreTrace.endCoreId) { ++ // CPU switching only occurs during scheduling ++ cpuSwitchTimes[SCHED_SUMMARY_VAILD]++; ++ } + } + } +- sched_tmp.second.schedSwitchDelay = delaySched; +- sched_tmp.second.schedSwitchTimes = schedSwitchTimes; +- sched_tmp.second.percentageSchedSwitch = delaySum == 0? 0.0 : delaySched * 1.0 / delaySum; +- sched_tmp.second.cpuSwitchTimes = cpuSwitchTimes; +- sched_tmp.second.delaySum = delaySum; ++ sched_tmp.second.vaildSchedSwitchDelay = vaildDelaySched; ++ sched_tmp.second.validPercentSchedSwitch = delaySum[SCHED_SUMMARY_VAILD] == 0 ? 0.0 : vaildDelaySched * 1.0 / delaySum[SCHED_SUMMARY_VAILD]; ++ sched_tmp.second.schedSwitchTimes[SCHED_SUMMARY_VAILD] = schedSwitchTimes[SCHED_SUMMARY_VAILD]; ++ sched_tmp.second.schedSwitchTimes[SCHED_SUMMARY_ALL] = schedSwitchTimes[SCHED_SUMMARY_ALL]; ++ sched_tmp.second.cpuSwitchTimes[SCHED_SUMMARY_VAILD] = cpuSwitchTimes[SCHED_SUMMARY_VAILD]; ++ sched_tmp.second.cpuSwitchTimes[SCHED_SUMMARY_ALL] = cpuSwitchTimes[SCHED_SUMMARY_ALL]; ++ sched_tmp.second.delaySum[SCHED_SUMMARY_VAILD] = delaySum[SCHED_SUMMARY_VAILD]; ++ sched_tmp.second.delaySum[SCHED_SUMMARY_ALL] = delaySum[SCHED_SUMMARY_ALL]; + } + } + +@@ -121,12 +158,15 @@ void SchedAnalysis::saveSchedInfoToFile() + if (pid == 0) { + continue; + } +- file << "pid," << pid << ","; +- file << "delaySum," << sched_tmp.second.delaySum << ","; +- file << "schedSwitchDelay," << sched_tmp.second.schedSwitchDelay << ","; +- file << "runtime," << sched_tmp.second.delaySum - sched_tmp.second.schedSwitchDelay << ","; +- file << "cpuSwitchTimes," << sched_tmp.second.cpuSwitchTimes << ","; +- file << std::endl; ++ file << "pid," << pid << "," << std::endl; ++ file << "cpuSwitchTimes," << sched_tmp.second.cpuSwitchTimes[SCHED_SUMMARY_ALL] << ","; ++ file << "schedSwitchTimes," << sched_tmp.second.schedSwitchTimes[SCHED_SUMMARY_ALL] << ","; ++ file << "delaySum," << sched_tmp.second.delaySum[SCHED_SUMMARY_ALL] << "," << std::endl; ++ file << "vaildCpuSwitchTimes," << sched_tmp.second.cpuSwitchTimes[SCHED_SUMMARY_VAILD] << ","; ++ file << "vaildSchedSwitchTimes," << sched_tmp.second.schedSwitchTimes[SCHED_SUMMARY_VAILD] << ","; ++ file << "validDelaySum," << sched_tmp.second.delaySum[SCHED_SUMMARY_VAILD] << ","; ++ file << "vaildSchedSwitchDelay," << sched_tmp.second.vaildSchedSwitchDelay << ","; ++ file << "validRuntime," << sched_tmp.second.delaySum[SCHED_SUMMARY_VAILD] - sched_tmp.second.vaildSchedSwitchDelay << "," << std::endl; + for (int coreIndex = 0; coreIndex < sched_tmp.second.runTimeOfCore.size(); coreIndex++) { + int run_time = sched_tmp.second.runTimeOfCore[coreIndex]; + if (run_time != 0) { +@@ -137,7 +177,16 @@ void SchedAnalysis::saveSchedInfoToFile() + for (const auto &coreTrace : sched_tmp.second.coreTrace) { + file << "startTime," << std::fixed << std::setprecision(6) << slv.convertTimeIntToDouble(coreTrace.startTime) << ","; + file << "endTime," << std::fixed << std::setprecision(6) << slv.convertTimeIntToDouble(coreTrace.endTime) << ","; +- file << "coreIndex," << coreTrace.coreIndex; ++ file << "startCoreId," << coreTrace.startCoreId << ","; ++ file << "endCoreId," << coreTrace.endCoreId << ","; ++ file << "coreTraceType,"; ++ if (coreTrace.coreTraceType == CORE_TRACE_INVALID) { ++ file << "invalid"; ++ } else if (coreTrace.coreTraceType == CORE_TRACE_SCHEDULING) { ++ file << "scheduling"; ++ } else if (coreTrace.coreTraceType == CORE_TRACE_ONCORE) { ++ file << "running"; ++ } + file << std::endl; + } + file << std::endl; +@@ -154,8 +203,7 @@ void SchedAnalysis::saveSchedInfoSummaryToFile() + std::cout << "file open failed:" << cfg.filename[FILE_TYPE_OUTPUT_SUMMARY_SCHED_INFO] << std::endl; + return; + } +- file << "pid,delaySum,schedSwitchDelay,schedSwitchPercentage,schedSwitchTimes,cpuSwitchTimes"; +- file << std::endl; ++ file << "pid,validDelaySum,vaildSchedSwitchDelay,validSchedSwitchPercentage,validSchedSwitchTimes,validCpuSwitchTimes" << std::endl; + TraceResolve &slv = TraceResolve::getInstance(); + for (const auto &sched_tmp : processSchedMap) { + int pid = sched_tmp.first; +@@ -163,12 +211,11 @@ void SchedAnalysis::saveSchedInfoSummaryToFile() + continue; + } + file << pid << ","; +- file << sched_tmp.second.delaySum << ","; +- file << sched_tmp.second.schedSwitchDelay << ","; +- file << std::fixed << std::setprecision(3) << sched_tmp.second.percentageSchedSwitch * 100 << "%,"; +- file << sched_tmp.second.schedSwitchTimes << ","; +- file << sched_tmp.second.cpuSwitchTimes << ","; +- file << std::endl; ++ file << sched_tmp.second.delaySum[SCHED_SUMMARY_VAILD] << ","; ++ file << sched_tmp.second.vaildSchedSwitchDelay << ","; ++ file << std::fixed << std::setprecision(3) << sched_tmp.second.validPercentSchedSwitch * 100 << "%,"; ++ file << sched_tmp.second.schedSwitchTimes[SCHED_SUMMARY_VAILD] << ","; ++ file << sched_tmp.second.cpuSwitchTimes[SCHED_SUMMARY_VAILD] << "," << std::endl; + } + + file.close(); +@@ -177,6 +224,8 @@ void SchedAnalysis::saveSchedInfoSummaryToFile() + void SchedAnalysis::schedAnalysisProc() + { + schedInfoProc(); ++ schedInfoVaildMark(); ++ + schedInfoAnalysis(); + saveSchedInfoToFile(); + saveSchedInfoSummaryToFile(); +diff --git a/extra-tools/da-tool/analysis/sched_analysis.h b/extra-tools/da-tool/analysis/sched_analysis.h +index 85036ce..2d2a9ed 100644 +--- a/extra-tools/da-tool/analysis/sched_analysis.h ++++ b/extra-tools/da-tool/analysis/sched_analysis.h +@@ -20,11 +20,29 @@ + #include + #include + ++typedef enum { ++ CORE_TRACE_INVALID, // valid when (s sr) or (sr s and startcore = endcore) ++ CORE_TRACE_SCHEDULING, // (s sr) ++ CORE_TRACE_ONCORE, // (sr s and startcore = endcore) ++ CORE_TRACE_MAX, ++} CORE_TRACE_E; ++ ++typedef enum { ++ SCHED_SUMMARY_VAILD, ++ SCHED_SUMMARY_ALL, // "all" means "valid" + "invalid" ++ SCHED_SUMMARY_MAX, ++} SCHED_SUMMARY_E; ++ + class ProcessCoreTrace { + public: + int startTime; + int endTime; +- int coreIndex; // -1 means sched_switch ++ int startCoreId; ++ int endCoreId; ++ bool startIsRet; // pid1->pid2 ret for pid2, not ret for pid1 ++ bool endIsRet; ++ ++ CORE_TRACE_E coreTraceType; + }; + + class ProcessSchedInfo { +@@ -33,11 +51,12 @@ public: + std::vector(CPU_CORE_NUM_MAX, 0)}; // Time running on each CPU + std::vector + coreTrace; // CPU information of pid in each time period +- int schedSwitchDelay; +- int schedSwitchTimes; +- double percentageSchedSwitch; +- int cpuSwitchTimes; +- int delaySum; ++ ++ int vaildSchedSwitchDelay; ++ double validPercentSchedSwitch; // valid / valid ++ int schedSwitchTimes[SCHED_SUMMARY_MAX]; ++ int cpuSwitchTimes[SCHED_SUMMARY_MAX]; ++ int delaySum[SCHED_SUMMARY_MAX]; + }; + + class CpuSchedTrace { +@@ -70,8 +89,9 @@ private: // process sched info + std::unordered_map processSchedMap; // [pid] + // std::vector > allCpuSchedInfo; // [coreIndex] + void processSchedAnalysisLoop(const int &pid, const int ×tamp, +- const int &coreIndex); ++ const int &coreIndex, const bool &isRet); + void schedInfoProc(); ++ void schedInfoVaildMark(); + void schedInfoAnalysis(); + void saveSchedInfoToFile(); + void saveSchedInfoSummaryToFile(); +diff --git a/extra-tools/da-tool/analysis/time_pair.cpp b/extra-tools/da-tool/analysis/time_pair.cpp +index 52aa6aa..024bbf6 100644 +--- a/extra-tools/da-tool/analysis/time_pair.cpp ++++ b/extra-tools/da-tool/analysis/time_pair.cpp +@@ -153,20 +153,6 @@ void TimePair::timePairUpdateLoop(const int &pid, const int &functionIndex, cons + timePairMap[pid].emplace(functionIndex, infoTmp); + } + +- Config &cfg = Config::getInstance(); +- bool isCfgSchedSwitch = cfg.funcCfgMap.count("sched_switch") > 0; +- int sched_switch_funcidx = -1; +- if (isCfgSchedSwitch) { +- sched_switch_funcidx = cfg.funcCfgMap["sched_switch"].functionIndex; +- const TraceResolve &trace_resolve_inst = TraceResolve::getInstance(); +- const FirstInfo &firstInfo = trace_resolve_inst.getTraceFirstInfo(); +- int coreIndex = line_info_tmp.core; +- // This process cannot find the starting sched switch on this core, ignore trace after timestamp +- if (timestamp <= firstInfo.schedSwitchTime[coreIndex] && functionIndex != sched_switch_funcidx && coreIndex != firstInfo.coreId) { +- timePairMap[pid][functionIndex].minEndTimeInvalid = timestamp; +- } +- } +- + if (isRet) { + if (timePairMap[pid][functionIndex].startTime.size() == 0) { // fist is endtime ,startime=endtime + timePairMap[pid][functionIndex].startTime.emplace_back(timestamp); +@@ -219,7 +205,6 @@ void TimePair::timePairAlignment() + for (auto &processInfo : timePairMap) { + for (auto &funcInfo : processInfo.second) { + int diffLen = funcInfo.second.startTime.size() - funcInfo.second.endTime.size(); +- bool updateEndTimeInvalid = false; + if (diffLen == 0) { + if (isOutputDebugFile) { + file << diffLen << "," << processInfo.first << " ," << funcInfo.first << " ," << \ +@@ -247,9 +232,8 @@ void TimePair::timePairAlignment() + for (int i = 0; i < diffLen; i++) { + int endTime = funcInfo.second.startTime[funcInfo.second.startTime.size() - diffLen + i]; + funcInfo.second.endTime.emplace_back(endTime); +- if (updateEndTimeInvalid == false) { ++ if (funcInfo.second.minEndTimeInvalid > endTime) { + funcInfo.second.minEndTimeInvalid = endTime; +- updateEndTimeInvalid = true; + } + } + } +@@ -303,8 +287,9 @@ void TimePair::timePairMarkInvalidData() + } + } + } +- validTimeOfPid[pid].validStartTime = validStartTime; +- validTimeOfPid[pid].validEndTime = validEndTime; ++ validTimeOfPid[pid].procStartTime = validStartTime; ++ validTimeOfPid[pid].procEndTime = validEndTime; ++ validTimeOfPid[pid].procTime = validEndTime - validStartTime; + } + + Config &cfg = Config::getInstance(); +@@ -315,8 +300,8 @@ void TimePair::timePairMarkInvalidData() + return; + } + for (const auto &range_info : validTimeOfPid) { +- file << "pid," << range_info.first << ",validStartTime ," << range_info.second.validStartTime << \ +- ", validEndTime ," << range_info.second.validEndTime << std::endl; ++ file << "pid," << range_info.first << ",procStartTime ," << range_info.second.procStartTime << \ ++ ", procEndTime ," << range_info.second.procEndTime << std::endl; + } + file.close(); + } +@@ -347,15 +332,17 @@ void TimePair::timePairMatching() + int functionIndex = cfg.funcCfgMap[functionName].functionIndex; + int isRet = cfg.funcCfgMap[functionName].isRet; + int debugPos = 0; +- int fatherFunction = getFatherFunctionIdLoop(pid, functionIndex, isRet, debugPos); +- saveFuncStkDebugToFile(file, pid, functionIndex, isRet, timestamp, fatherFunction, debugPos); +- timePairUpdateLoop(pid, functionIndex, isRet, timestamp, fatherFunction, line_info_tmp); ++ if (line_info_tmp.traceValid[TRACE_VALID_FUNC] || line_info_tmp.traceValid[TRACE_VALID_SCHED_SWITCH_PREV]) { ++ int fatherFunction = getFatherFunctionIdLoop(pid, functionIndex, isRet, debugPos); ++ saveFuncStkDebugToFile(file, pid, functionIndex, isRet, timestamp, fatherFunction, debugPos); ++ timePairUpdateLoop(pid, functionIndex, isRet, timestamp, fatherFunction, line_info_tmp); ++ } + +- if (isCfgSchedSwitch && functionIndex == sched_switch_funcidx) // pid1->pid2 : pid1->sched() sched_ret()->pid2 ++ if (isCfgSchedSwitch && functionIndex == sched_switch_funcidx && line_info_tmp.traceValid[TRACE_VALID_SCHED_SWITCH_NEXT]) // pid1->pid2 : pid1->sched() sched_ret()->pid2 + { + int nextPid = line_info_tmp.schedSwitchLine.nextPid; + isRet = 1; +- fatherFunction = getFatherFunctionIdLoop(nextPid, functionIndex, isRet, debugPos); ++ int fatherFunction = getFatherFunctionIdLoop(nextPid, functionIndex, isRet, debugPos); + saveFuncStkDebugToFile(file, nextPid, functionIndex, isRet, timestamp, fatherFunction, debugPos); + timePairUpdateLoop(nextPid, functionIndex, isRet, timestamp, fatherFunction, line_info_tmp); + } +@@ -363,6 +350,23 @@ void TimePair::timePairMatching() + file.close(); + } + ++void TimePair::functionDelayUpdateValidTimeLoop(const int &pid, const int ×tamp, const bool &valid) ++{ ++ ++ int lastTimeValid = validTimeOfPid[pid].lastTimeValid; ++ if (!lastTimeValid && valid) { ++ validTimeOfPid[pid].validStartTime.emplace_back(timestamp); ++ validTimeOfPid[pid].validEndTime.emplace_back(timestamp); ++ } ++ ++ int size = validTimeOfPid[pid].validEndTime.size(); ++ if (valid && size > 0) { ++ validTimeOfPid[pid].validEndTime[size - 1] = timestamp; ++ } ++ ++ validTimeOfPid[pid].lastTimeValid = valid; ++} ++ + void TimePair::functionDelayUpdate() + { + for (auto &processInfo : timePairMap) { +@@ -372,6 +376,33 @@ void TimePair::functionDelayUpdate() + } + } + } ++ ++ Config &cfg = Config::getInstance(); ++ int sched_switch_funcidx = cfg.funcCfgMap["sched_switch"].functionIndex; ++ TraceResolve &trace_resolve_inst = TraceResolve::getInstance(); ++ for (const auto &line_info_tmp : trace_resolve_inst.getTraceLine()) { ++ std::string functionName = line_info_tmp.functionName; ++ if (cfg.funcCfgMap.count(functionName) == 0) { ++ continue; ++ } ++ int pid = line_info_tmp.pid; ++ int timestamp = line_info_tmp.timestamp; ++ int functionIndex = cfg.funcCfgMap[functionName].functionIndex; ++ if (functionIndex == sched_switch_funcidx) { ++ int nextPid = line_info_tmp.schedSwitchLine.nextPid; ++ functionDelayUpdateValidTimeLoop(pid, timestamp, line_info_tmp.traceValid[TRACE_VALID_SCHED_SWITCH_PREV]); ++ functionDelayUpdateValidTimeLoop(nextPid, timestamp, line_info_tmp.traceValid[TRACE_VALID_SCHED_SWITCH_NEXT]); ++ } else { ++ functionDelayUpdateValidTimeLoop(pid, timestamp, line_info_tmp.traceValid[TRACE_VALID_FUNC]); ++ } ++ } ++ ++ for (auto &processInfo : validTimeOfPid) { ++ int pid = processInfo.first; ++ for (int i = 0; i < processInfo.second.validStartTime.size(); i++) { ++ validTimeOfPid[pid].validTime += (processInfo.second.validEndTime[i] - processInfo.second.validStartTime[i]); ++ } ++ } + } + + void TimePair::functionStatisticsAnalysis() +@@ -448,7 +479,7 @@ void TimePair::saveTimePairToFile() + file << "maxStartTimeInvaild:" << funcInfo.second.maxStartTimeInvaild << ","; + file << "minEndTimeInvalid:" << funcInfo.second.minEndTimeInvalid << "," << std::endl; + file << "info num," << funcInfo.second.startTime.size() << ",valid info num," << funcInfo.second.summary.callTimes[DELAY_INFO_ALL] << ","; +- file << "validStartTime," << validTimeOfPid[pid].validStartTime << ",validEndTime," << validTimeOfPid[pid].validEndTime << std::endl; ++ file << "procStartTime," << validTimeOfPid[pid].procStartTime << ",procEndTime," << validTimeOfPid[pid].procEndTime << std::endl; + file << "startTime" << ","; + for (const auto &startTime : funcInfo.second.startTime) { + file << std::fixed << std::setprecision(6) << startTime << ","; +@@ -544,14 +575,22 @@ void TimePair::saveDelayInfoToFile() + } + + +-int TimePair::getProcessValidTime(const int &pid) ++int TimePair::getProcessTime(const int &pid) + { + if (validTimeOfPid.count(pid) != 0) { +- return validTimeOfPid[pid].validEndTime - validTimeOfPid[pid].validStartTime; ++ return validTimeOfPid[pid].procTime; + } else { + return 0; + } ++} + ++int TimePair::getProcessValidTime(const int &pid) ++{ ++ if (validTimeOfPid.count(pid) != 0) { ++ return validTimeOfPid[pid].validTime; ++ } else { ++ return 0; ++ } + } + + void TimePair::timePairAnalysis() +diff --git a/extra-tools/da-tool/analysis/time_pair.h b/extra-tools/da-tool/analysis/time_pair.h +index ba0b784..925a017 100644 +--- a/extra-tools/da-tool/analysis/time_pair.h ++++ b/extra-tools/da-tool/analysis/time_pair.h +@@ -23,8 +23,16 @@ + + class VaildRange { + public: +- int validStartTime; +- int validEndTime; ++ // Invalid timestamps divide the trace into several valid parts ++ std::vector validStartTime; ++ std::vector validEndTime; ++ ++ int procStartTime{0}; ++ int procEndTime{0}; ++ int procTime{0}; ++ int validTime{0}; ++ // tmp var ++ bool lastTimeValid{false}; + }; + + typedef enum { +@@ -67,7 +75,7 @@ public: + std::vector fatherFuncPos; + std::vector childFuncTimes; // Number of calls to other functions. + std::vector retVal; // return value +- std::vector isInvalid; // isInvalid=true indicates that there is no ++ std::vector isInvalid; // isInvalid=true indicates that there is no + // complete call stack data + std::vector strFunctionStk; + +@@ -90,7 +98,6 @@ public: + ~TimePair() {} + + private: +- // [pid].start/end Record the start and end times of valid traces + std::unordered_map validTimeOfPid; + // Store function call stacks for each pid + std::unordered_map> funcStkMap; +@@ -109,6 +116,8 @@ private: + const int ×tamp, const int &fatherFunction, + const int &debugPos); + void functionDelayUpdate(); ++ void functionDelayUpdateValidTimeLoop(const int &pid, const int ×tamp, ++ const bool &valid); + void functionStatisticsAnalysis(); + + void timePairMatching(); +@@ -122,6 +131,7 @@ public: + const std::unordered_map> & + getTimePairMap() const; + int getProcessValidTime(const int &pid); ++ int getProcessTime(const int &pid); + void timePairAnalysis(); + }; + +diff --git a/extra-tools/da-tool/analysis/trace_resolve.cpp b/extra-tools/da-tool/analysis/trace_resolve.cpp +index 61f0a74..ae86773 100644 +--- a/extra-tools/da-tool/analysis/trace_resolve.cpp ++++ b/extra-tools/da-tool/analysis/trace_resolve.cpp +@@ -56,12 +56,6 @@ const std::vector &TraceResolve::getTraceLine() const + return traceLineVec; + } + +-const FirstInfo &TraceResolve::getTraceFirstInfo() const +-{ +- return firstInfo; +-} +- +- + void SchedSwitchLine::processStateToEnum(std::string state) + { + if (state == "R") { +@@ -74,7 +68,8 @@ void SchedSwitchLine::processStateToEnum(std::string state) + } + } + +-int countLines(const std::string& filename) { ++int countLines(const std::string &filename) ++{ + std::ifstream file(filename); + if (!file.is_open()) { + std::cout << "file open failed:" << filename << std::endl; +@@ -130,7 +125,7 @@ void TraceResolve::resolveTrace() + continue; + } + if (line_num % 10000 == 0) { +- double rate = (line_num - cfg.readTraceBegin) * 1.0/ readTraceLen; ++ double rate = (line_num - cfg.readTraceBegin) * 1.0 / readTraceLen; + std::cout << "\r" << "[Resolve] " << std::fixed << std::setprecision(3) << rate * 100 << "%, "; + std::cout << "Match " << regex_num; + std::cout.flush(); +@@ -178,9 +173,6 @@ void TraceResolve::resolveTrace() + if (isMatch) { + if (isFirstMatch) { + startTimeIntPart = std::stoi(match[TRACE_INFO_TIMESTAMP_INT].str()); +- firstInfo.coreId = std::stoi(match[TRACE_INFO_CPU].str()); +- firstInfo.startTime = (std::stoi(match[TRACE_INFO_TIMESTAMP_INT].str()) - startTimeIntPart) * MICRO_PER_SEC \ +- + std::stoi(match[TRACE_INFO_TIMESTAMP_FLOAT].str()); + isFirstMatch = false; + } + match_info.timestamp = (std::stoi(match[TRACE_INFO_TIMESTAMP_INT].str()) - startTimeIntPart) * MICRO_PER_SEC \ +@@ -190,6 +182,10 @@ void TraceResolve::resolveTrace() + match_info.functionName = match[TRACE_INFO_FUNCNAME].str(); + match_info.traceLineNum = line_num; + ++ match_info.traceValid[TRACE_VALID_FUNC] = false; ++ match_info.traceValid[TRACE_VALID_SCHED_SWITCH_PREV] = false; ++ match_info.traceValid[TRACE_VALID_SCHED_SWITCH_NEXT] = false; ++ + traceLineVec.emplace_back(match_info); + regex_num++; + } +@@ -224,15 +220,22 @@ void TraceResolve::saveTraceRegexRstToFile() + return; + } + +- file << "traceLineNum" << "," << "pid" << "," << "core" << "," << "timestamp" << "," << "functionName" << std::endl; ++ file << "traceLineNum,pid,core,timestamp,functionName,"; ++ file << "prevPid,prevPrio,prevState,nextPid,nextPrio,"; ++ file << "funcValid,schedPrevValid,schedNextValid" << std::endl; + for (const auto &row : traceLineVec) { + file << row.traceLineNum << ","; +- file << row.pid << "," << row.core << "," << "," << std::fixed << std::setprecision(6) << \ ++ file << row.pid << "," << row.core << "," << std::fixed << std::setprecision(6) << \ + row.timestamp * 1.0 / MICRO_PER_SEC + startTimeIntPart << "," << row.functionName; + if (row.functionName == "sched_switch") { + file << "," << row.schedSwitchLine.prevPid << "," << row.schedSwitchLine.prevPrio << "," << \ + row.schedSwitchLine.prevState << "," << row.schedSwitchLine.nextPid << "," << row.schedSwitchLine.nextPrio; ++ } else { ++ file << ",,,,,"; + } ++ file << "," << row.traceValid[TRACE_VALID_FUNC]; ++ file << "," << row.traceValid[TRACE_VALID_SCHED_SWITCH_PREV]; ++ file << "," << row.traceValid[TRACE_VALID_SCHED_SWITCH_NEXT]; + file << std::endl; + } + +@@ -245,64 +248,188 @@ double TraceResolve::convertTimeIntToDouble(const int ×tamp) + return timestamp * 1.0 / MICRO_PER_SEC + startTimeIntPart; + } + +-void TraceResolve::firstSchedSwitchTimeAnalysis() ++void FuncValid::addToVectors(int traceId, bool isR, bool val) ++{ ++ traceLineIndex.emplace_back(traceId); ++ isRet.emplace_back(isR); ++ valid.emplace_back(val); ++} ++ ++void TraceResolve::creatEmptyFuncPairMap(const int &pid, const int &funcIndex) + { ++ if (funcPairMap.count(pid) == 0) { ++ std::unordered_map funcValidMapTmp; ++ funcPairMap.emplace(pid, funcValidMapTmp); ++ } ++ ++ if (funcPairMap[pid].count(funcIndex) == 0) { ++ FuncValid funcVaildTmp; ++ funcPairMap[pid].emplace(funcIndex, funcVaildTmp); ++ } ++} ++ ++void TraceResolve::funcPairMapInit() ++{ ++ // [pid][func] + Config &cfg = Config::getInstance(); +- bool isCfgSchedSwitch = cfg.funcCfgMap.count("sched_switch") > 0; +- int sched_switch_funcidx = -1; +- if (isCfgSchedSwitch) { +- sched_switch_funcidx = cfg.funcCfgMap["sched_switch"].functionIndex; +- } else { ++ for (int traceId = 0; traceId < traceLineVec.size(); traceId++) { ++ int pid = traceLineVec[traceId].pid; ++ std::string functionName = traceLineVec[traceId].functionName; ++ int functionIndex = cfg.funcCfgMap[functionName].functionIndex; ++ int isRet = cfg.funcCfgMap[functionName].isRet == 0 ? false : true; ++ ++ creatEmptyFuncPairMap(pid, functionIndex); ++ funcPairMap[pid][functionIndex].addToVectors(traceId, isRet, false); ++ ++ if (traceLineVec[traceId].functionName == "sched_switch") { ++ int nextPid = traceLineVec[traceId].schedSwitchLine.nextPid; ++ creatEmptyFuncPairMap(nextPid, functionIndex); ++ funcPairMap[nextPid][functionIndex].addToVectors(traceId, true, false); ++ } ++ } ++ ++ for (auto &processInfo : funcPairMap) { ++ for (auto &funcInfo : processInfo.second) { ++ for (int i = 0; i < funcInfo.second.isRet.size() - 1; i++) { ++ // a a a a a_r a_r a_r, a a_r is valid trace ++ if (!funcInfo.second.isRet[i] && funcInfo.second.isRet[i + 1]) { ++ funcInfo.second.valid[i] = true; ++ funcInfo.second.valid[i + 1] = true; ++ } ++ } ++ } ++ } ++ ++ saveFuncPairMapToFile(); ++} ++ ++void TraceResolve::saveFuncPairMapToFile() ++{ ++ Config &cfg = Config::getInstance(); ++ if (cfg.getDebugLevel() < DEBUG_LEVEL_2) { ++ return; ++ } ++ ++ std::ofstream file(cfg.filename[FILE_TYPE_DEBUG_TRACE_FUNCPAIRMAP], std::ios::out | std::ios::trunc); ++ if (!file) { ++ std::cout << "file open failed:" << cfg.filename[FILE_TYPE_DEBUG_TRACE_FUNCPAIRMAP] << std::endl; + return; + } + +- firstInfo.schedSwitchTime.resize(CPU_CORE_NUM_MAX, INT_MAX); +- firstInfo.coreTime.resize(CPU_CORE_NUM_MAX, INT_MAX); +- firstInfo.schedSwitchTime[firstInfo.coreId] = firstInfo.startTime; +- firstInfo.coreTime[firstInfo.coreId] = firstInfo.startTime; ++ for (const auto &processInfo : funcPairMap) { + +- for (const auto &line_info_tmp : traceLineVec) { +- std::string functionName = line_info_tmp.functionName; +- int pid = line_info_tmp.pid; +- if (cfg.funcCfgMap.count(functionName) == 0) { +- continue; ++ for (const auto &funcInfo : processInfo.second) { ++ int funcIndex = funcInfo.first; ++ file << "pid," << processInfo.first; ++ file << ",funcid," << funcIndex; ++ file << ",funcName," << cfg.IndexToFunction[funcIndex] << std::endl; ++ file << "isRet,"; ++ for (int i = 0; i < funcInfo.second.isRet.size(); i++) { ++ file << funcInfo.second.isRet[i] << ","; ++ } ++ file << std::endl; ++ file << "valid,"; ++ for (int i = 0; i < funcInfo.second.valid.size(); i++) { ++ file << funcInfo.second.valid[i] << ","; ++ } ++ file << std::endl; ++ file << "traceLineIndex,"; ++ for (int i = 0; i < funcInfo.second.traceLineIndex.size(); i++) { ++ file << funcInfo.second.traceLineIndex[i] << ","; ++ } ++ file << std::endl; + } ++ } + +- int timestamp = line_info_tmp.timestamp; +- int coreIndex = line_info_tmp.core; +- int functionIndex = cfg.funcCfgMap[functionName].functionIndex; +- // first appearance of coreIndex in trace +- if (firstInfo.coreTime[coreIndex] == INT_MAX) { +- firstInfo.coreTime[coreIndex] = timestamp; +- } +- // first appearance of sched_switch in coreIndex's trace +- if (functionIndex == sched_switch_funcidx && firstInfo.schedSwitchTime[coreIndex] == INT_MAX) { +- firstInfo.schedSwitchTime[coreIndex] = timestamp; ++ file.close(); ++} ++ ++void TraceResolve::markTraceIsValid() ++{ ++ Config &cfg = Config::getInstance(); ++ int sched_switch_funcidx = cfg.funcCfgMap["sched_switch"].functionIndex; ++ ++ for (auto &processInfo : funcPairMap) { ++ for (auto &funcInfo : processInfo.second) { ++ int functionIndex = funcInfo.first; ++ for (int i = 0; i < funcInfo.second.valid.size(); i++) { ++ bool validTmp = funcInfo.second.valid[i]; ++ int traceId = funcInfo.second.traceLineIndex[i]; ++ if (functionIndex == sched_switch_funcidx) { ++ // pid1 -> s s_r ->pid2 ++ if (funcInfo.second.isRet[i]) { ++ traceLineVec[traceId].traceValid[TRACE_VALID_SCHED_SWITCH_NEXT] = validTmp; ++ } else { ++ traceLineVec[traceId].traceValid[TRACE_VALID_SCHED_SWITCH_PREV] = validTmp; ++ } ++ } else { ++ traceLineVec[traceId].traceValid[TRACE_VALID_FUNC] = validTmp; ++ } ++ } + } + } + } + +-void TraceResolve::trace_resolve_proc() ++void TraceResolve::markFuncStkValidLoop(const int &pid, const int &funcIndex, const int &traceId, const TRACE_VALID_E &validType) + { +- resolveTrace(); +- saveTraceRegexRstToFile(); ++ if (funcStkValidMap.count(pid) == 0) { ++ FuncStkValid funcStkVaildTmp; ++ funcStkValidMap.emplace(pid, funcStkVaildTmp); ++ } ++ ++ bool traceValid = traceLineVec[traceId].traceValid[validType]; ++ if (!traceValid) { ++ funcStkValidMap[pid].isInvalid = true; ++ } else { ++ funcStkValidMap[pid].traceIndex.emplace_back(traceId); ++ funcStkValidMap[pid].vaildType.emplace_back(validType); ++ if (!funcStkValidMap[pid].funcStk.empty() && funcIndex == funcStkValidMap[pid].funcStk.back()) { ++ funcStkValidMap[pid].funcStk.pop_back(); ++ } else { ++ funcStkValidMap[pid].funcStk.emplace_back(funcIndex); ++ } ++ } + +- firstSchedSwitchTimeAnalysis(); ++ if (funcStkValidMap[pid].funcStk.size() == 0) { ++ if (funcStkValidMap[pid].isInvalid) { ++ for (int i = 0; i < funcStkValidMap[pid].traceIndex.size(); i++) { ++ int traceIndexTmp = funcStkValidMap[pid].traceIndex[i]; ++ TRACE_VALID_E vaildTypeTmp = funcStkValidMap[pid].vaildType[i]; ++ traceLineVec[traceIndexTmp].traceValid[vaildTypeTmp] = false; ++ } ++ } ++ // clear history ++ funcStkValidMap[pid].traceIndex.resize(0); ++ funcStkValidMap[pid].vaildType.resize(0); ++ funcStkValidMap[pid].isInvalid = false; ++ } + } + +-void TraceResolve::trace_check_show() ++void TraceResolve::markFuncStkValid() + { + Config &cfg = Config::getInstance(); +- for (int coreId = 0; coreId < CPU_CORE_NUM_MAX; coreId++) { +- int firstSchedSwitchTime = firstInfo.schedSwitchTime[coreId]; +- int firstCoreTime = firstInfo.coreTime[coreId]; +- if (cfg.getDebugLevel() >= DEBUG_LEVEL_1) { +- std::cout << "coreId:" << coreId; +- std::cout << ",firstSchedSwitchTime:" << firstSchedSwitchTime; +- std::cout << ",firstCoreTime:" << firstCoreTime << std::endl; +- } +- if (firstSchedSwitchTime != firstCoreTime) { +- std::cout << "[ERROR] core " << coreId << " missing starting scheduling information, result maybe error!!!" << std::endl; ++ int sched_switch_funcidx = cfg.funcCfgMap["sched_switch"].functionIndex; ++ for (int traceId = 0; traceId < traceLineVec.size(); traceId++) { ++ int pid = traceLineVec[traceId].pid; ++ std::string functionName = traceLineVec[traceId].functionName; ++ int functionIndex = cfg.funcCfgMap[functionName].functionIndex; ++ if (functionIndex == sched_switch_funcidx) { ++ int nextPid = traceLineVec[traceId].schedSwitchLine.nextPid; ++ markFuncStkValidLoop(pid, functionIndex, traceId, TRACE_VALID_SCHED_SWITCH_PREV); ++ markFuncStkValidLoop(nextPid, functionIndex, traceId, TRACE_VALID_SCHED_SWITCH_NEXT); ++ } else { ++ markFuncStkValidLoop(pid, functionIndex, traceId, TRACE_VALID_FUNC); + } + } ++} ++ ++void TraceResolve::trace_resolve_proc() ++{ ++ resolveTrace(); ++ // trace valid check ++ funcPairMapInit(); ++ markTraceIsValid(); ++ markFuncStkValid(); ++ ++ saveTraceRegexRstToFile(); + } +\ No newline at end of file +diff --git a/extra-tools/da-tool/analysis/trace_resolve.h b/extra-tools/da-tool/analysis/trace_resolve.h +index e943d20..4b8ba89 100644 +--- a/extra-tools/da-tool/analysis/trace_resolve.h ++++ b/extra-tools/da-tool/analysis/trace_resolve.h +@@ -21,11 +21,10 @@ + #include + + // include\linux\sched.h +-typedef enum +-{ +- PROCESS_STATE_TASK_RUNNING, // R +- PROCESS_STATE_TASK_INTERRUPTIBLE, // S +- PROCESS_STATE_MAX, ++typedef enum { ++ PROCESS_STATE_TASK_RUNNING, // R ++ PROCESS_STATE_TASK_INTERRUPTIBLE, // S ++ PROCESS_STATE_MAX, + } PROCESS_STATE_E; + + class SchedSwitchLine { +@@ -40,6 +39,13 @@ public: + void processStateToEnum(std::string state); + }; + ++typedef enum { ++ TRACE_VALID_FUNC, ++ TRACE_VALID_SCHED_SWITCH_PREV, ++ TRACE_VALID_SCHED_SWITCH_NEXT, ++ TRACE_VALID_MAX, ++} TRACE_VALID_E; ++ + class TraceLineReslove { + public: + int traceLineNum; +@@ -52,14 +58,24 @@ public: + + // after convert + int functionIndex; ++ bool traceValid[TRACE_VALID_MAX]; ++}; ++ ++class FuncValid { ++public: ++ std::vector traceLineIndex; ++ std::vector isRet; ++ std::vector valid; // rst ++ ++ void addToVectors(int traceId, bool isR, bool val); + }; + +-class FirstInfo { ++class FuncStkValid { + public: +- std::vector schedSwitchTime; // [coreId] +- std::vector coreTime; // [coreId] +- int coreId; // first core in trace +- int startTime; ++ std::vector funcStk; ++ std::vector traceIndex; ++ std::vector vaildType; // size() = traceIndex.size(); ++ bool isInvalid{false}; // tmp rst + }; + + class TraceResolve { +@@ -80,12 +96,20 @@ private: // regex + void saveTraceRegexRstToFile(); + + private: +- FirstInfo firstInfo; +- void firstSchedSwitchTimeAnalysis(); ++ // [pid][functionIndex] mark unmatch func => invalid ++ std::unordered_map> funcPairMap; ++ // [pid] if funcstk have invalid data, mark all funcstk invalid ++ std::unordered_map funcStkValidMap; ++ void creatEmptyFuncPairMap(const int &pid, const int &funcIndex); ++ void funcPairMapInit(); ++ void markTraceIsValid(); ++ void markFuncStkValid(); ++ void markFuncStkValidLoop(const int &pid, const int &funcIndex, ++ const int &traceId, const TRACE_VALID_E &validType); ++ void saveFuncPairMapToFile(); + + public: + const std::vector &getTraceLine() const; +- const FirstInfo &getTraceFirstInfo() const; + double convertTimeIntToDouble(const int ×tamp); + void trace_resolve_proc(); + void trace_check_show(); +diff --git a/extra-tools/da-tool/main.cpp b/extra-tools/da-tool/main.cpp +index 34652f0..abc1004 100644 +--- a/extra-tools/da-tool/main.cpp ++++ b/extra-tools/da-tool/main.cpp +@@ -37,7 +37,6 @@ int main(int argc, char *argv[]) + FunctionStack &fstk = FunctionStack::getInstance(); + fstk.function_stack_proc(); + +- trace_resolve_inst.trace_check_show(); + cout << "[STEP 2-2] analysis finish" << endl; + return 0; + } +\ No newline at end of file +diff --git a/extra-tools/da-tool/script/da-tool.sh b/extra-tools/da-tool/script/da-tool.sh +index 2b38bc8..3bfa366 100755 +--- a/extra-tools/da-tool/script/da-tool.sh ++++ b/extra-tools/da-tool/script/da-tool.sh +@@ -31,8 +31,9 @@ cd $base_dir + mkdir -p tmp + + # extern para +-sleep_time=10 +-sleep_time_max=100 ++sleep_time_default=1 ++sleep_time=$sleep_time_default ++sleep_time_max=10 + + # base para + declare -a kernel_symbols +@@ -79,10 +80,18 @@ function usage() { + echo "usage: da-tool.sh [OPTIONS] [ARGS]" + echo "" + echo "The most commonly used da-tool.sh options are:" +- echo " -t set tracing duration, unit: seconds, 1<=duration<=100, default is 10" ++ echo " -t set tracing duration, unit: seconds, 1<=duration<=$sleep_time_max, default is $sleep_time_default" + echo " -h show usage" + } + ++function sleep_time_check() { ++ if [ $sleep_time -ge $((sleep_time_max + 1)) ] || [ $sleep_time -le 0 ]; then ++ echo "sampling time should > 0 and <= $sleep_time_max" ++ usage ++ exit 1 ++ fi ++} ++ + # get opt + # while getopts "b:l:t:p:as" opt; do # debug + while getopts "t:h" opt; do +@@ -99,9 +108,9 @@ while getopts "t:h" opt; do + if [[ $OPTARG =~ ^[0-9]{1,3}$ ]]; then + sleep_time=$OPTARG + else +- usage +- exit 1 ++ sleep_time=0 + fi ++ sleep_time_check + ;; + p) + parameter="$OPTARG" +@@ -161,7 +170,7 @@ function arr_repet_ele_check() { + for element in "${arr[@]}"; do + count=$(printf '%s\n' "${arr[@]}" | grep -c -w "$element") + if [ $count -ge 2 ]; then +- echo " '$element' duplicate configuration, please check '$config_file'!!!" ++ echo " '$element' duplicate configuration" + exit 1 + fi + done +@@ -172,7 +181,7 @@ function arr_check_function_support() { + local symbols_tmp=("$@") + for symbol in "${symbols_tmp[@]}"; do + if [[ $symbol =~ \. ]]; then +- echo "$symbol have '.', not support, please check '$config_file!!!'" | tee -a $sample_log ++ echo "$symbol have '.', not support" | tee -a $sample_log + exit 1 + fi + done +@@ -181,12 +190,18 @@ function arr_check_function_support() { + # kernel symbols should be found in '/proc/kallsyms' + function arr_check_kernel_symbols_exist() { + local symbols_tmp=("$@") ++ kernel_symbols=() + for symbol in "${symbols_tmp[@]}"; do + if grep -e "^[0-9a-fA-F]* [a-zA-Z] $symbol$" /proc/kallsyms >/dev/null; then + echo "$symbol exist in /proc/kallsyms" >>$sample_log ++ # first version ++ # (1) only support kernel symbols ++ # (2) can't config /etc/da-tool.conf ++ # (3) if symbols not in /proc/kallsyms, then continue(not exit) ++ kernel_symbols[${#kernel_symbols[*]}]+=$symbol + else +- echo "$symbol does not exist in /proc/kallsyms or not support, please check '$config_file'!!!" | tee -a $sample_log +- exit 1 ++ echo "$symbol does not exist in /proc/kallsyms or not support" | tee -a $sample_log ++ # exit 1 # after first version + fi + done + } +@@ -199,7 +214,7 @@ function arr_check_user_symbols_exist() { + if nm "$binary" | grep -q "\<$symbol\>"; then + echo "$symbol dost exist in $binary" >>$sample_log + else +- echo "$symbol does not exist in $binary, please check '$config_file'!!!" | tee -a $sample_log ++ echo "$symbol does not exist in $binary" | tee -a $sample_log + exit 1 + fi + done +@@ -211,7 +226,7 @@ function arr_check_sched() { + if [[ $sched == "sched_switch" ]]; then + echo "sched_switch match" >>$sample_log + else +- echo "s only support sched_switch, please check '$config_file'!!!" | tee -a $sample_log ++ echo "s only support sched_switch" | tee -a $sample_log + exit 1 + fi + done +@@ -301,20 +316,6 @@ function gen_config_for_analysis() { + done + } + +-function opt_check() { +- if [ $is_uprobe_sample = false ] && [ $is_kprobe_sample = false ]; then +- echo "use -m u|k|uk to set uprobe/kprobe/both" +- usage +- exit 1 +- fi +- +- if [ $sleep_time -ge $((sleep_time_max + 1)) ] || [ $sleep_time -le 0 ]; then +- echo "sampling time should > 0 and <= $sleep_time_max" +- usage +- exit 1 +- fi +-} +- + function clear_env() { + echo "[INFO] clear env..." + echo 0 >/sys/kernel/debug/tracing/tracing_on +@@ -369,6 +370,7 @@ function sample_init() { + echo >/sys/kernel/debug/tracing/trace + echo 40960 >/sys/kernel/debug/tracing/buffer_size_kb + ++ + echo >/sys/kernel/debug/tracing/uprobe_events + echo >/sys/kernel/debug/tracing/kprobe_events + } +@@ -538,8 +540,6 @@ if [ $is_clear = true ]; then + exit 1 + fi + +-opt_check +- + if [ $is_analysis_only_mode = true ]; then # only analysis + trace_analysis + exit 1 +-- +2.33.0 + diff --git a/aops-ceres.spec b/aops-ceres.spec index ef85f7928a4216f39e5de04649cd731ec38dfbdf..cf6d7e16fc8cef8f2a2c378f269828b0a8ef7372 100644 --- a/aops-ceres.spec +++ b/aops-ceres.spec @@ -2,7 +2,7 @@ Name: aops-ceres Version: v1.3.4 -Release: 11 +Release: 12 Summary: An agent which needs to be adopted in client, it managers some plugins, such as gala-gopher(kpi collection), fluentd(log collection) and so on. License: MulanPSL2 URL: https://gitee.com/openeuler/%{name} @@ -19,6 +19,7 @@ Patch0009: 0009-Dealing-with-situations-where-sched-are-missing.patch Patch0010: 0010-Soft-links-for-documents.patch Patch0011: 0011-fix-valid-time-of-pid-at-first-core-and-add-case.patch Patch0012: 0012-update-doc-link.patch +Patch0013: 0013-restrict-function-redesign-trace-check-proc.patch BuildRequires: python3-setuptools Requires: python3-requests python3-jsonschema python3-libconf @@ -76,9 +77,9 @@ cp -r hotpatch %{buildroot}/%{python3_sitelib}/dnf-plugins/ # install for da-tool mkdir -p ${RPM_BUILD_ROOT}%{_bindir} mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir} -install -b -m640 ./extra-tools/da-tool/conf/da-tool.conf ${RPM_BUILD_ROOT}%{_sysconfdir}/ -install -b -m755 ./extra-tools/da-tool/build/da-tool-analysis ${RPM_BUILD_ROOT}%{_bindir}/ -install -b -m755 ./extra-tools/da-tool/script/da-tool.sh ${RPM_BUILD_ROOT}%{_bindir}/ +install -b -m400 ./extra-tools/da-tool/conf/da-tool.conf ${RPM_BUILD_ROOT}%{_sysconfdir}/ +install -b -m500 ./extra-tools/da-tool/build/da-tool-analysis ${RPM_BUILD_ROOT}%{_bindir}/ +install -b -m500 ./extra-tools/da-tool/script/da-tool.sh ${RPM_BUILD_ROOT}%{_bindir}/ %files %doc README.* @@ -94,10 +95,14 @@ install -b -m755 ./extra-tools/da-tool/script/da-tool.sh ${RPM_BUILD_ROOT} %files -n da-tool %defattr (-, root, root) %config(noreplace) %{_sysconfdir}/da-tool.conf -%attr(755, root, root) %{_bindir}/da-tool.sh -%attr(755, root, root) %{_bindir}/da-tool-analysis +%attr(0500, root, root) %{_bindir}/da-tool.sh +%attr(0500, root, root) %{_bindir}/da-tool-analysis %changelog +* Mon Dec 4 2023 liuchanggeng - v1.3.4-12 +- to maintain functional stability, da-tool only releases network related analysis +- it is not allowed to modify the configuration file of the da-tool + * Tue Nov 28 2023 liuchanggeng - v1.3.4-11 - da-tool consider trace as valid data when first core lost scheduling information - update document