aops-ceres/0013-restrict-function-redesign-trace-check-proc.patch
LHesperus 50ac8ba057 1.3.4-12 datool restrict function
(cherry picked from commit b751b1f60c4bd963bb909c697b80de872d0c34ff)
2023-12-04 11:56:28 +08:00

1134 lines
46 KiB
Diff

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<int> delay[FS_DELAY_TYPE_MAX];
std::vector<uintptr_t> 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 &timestamp, const int &coreIndex)
+void SchedAnalysis::processSchedAnalysisLoop(const int &pid, const int &timestamp, 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 &timestam
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 <unordered_map>
#include <vector>
+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<int>(CPU_CORE_NUM_MAX, 0)}; // Time running on each CPU
std::vector<ProcessCoreTrace>
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<int, ProcessSchedInfo> processSchedMap; // [pid]
// std::vector <std::vector<CpuSchedInfo>> allCpuSchedInfo; // [coreIndex]
void processSchedAnalysisLoop(const int &pid, const int &timestamp,
- 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 &timestamp, 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<int> validStartTime;
+ std::vector<int> 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<int> fatherFuncPos;
std::vector<int> childFuncTimes; // Number of calls to other functions.
std::vector<uintptr_t> retVal; // return value
- std::vector<bool> isInvalid; // isInvalid=true indicates that there is no
+ std::vector<bool> isInvalid; // isInvalid=true indicates that there is no
// complete call stack data
std::vector<std::string> strFunctionStk;
@@ -90,7 +98,6 @@ public:
~TimePair() {}
private:
- // [pid].start/end Record the start and end times of valid traces
std::unordered_map<int, VaildRange> validTimeOfPid;
// Store function call stacks for each pid
std::unordered_map<int, std::vector<int>> funcStkMap;
@@ -109,6 +116,8 @@ private:
const int &timestamp, const int &fatherFunction,
const int &debugPos);
void functionDelayUpdate();
+ void functionDelayUpdateValidTimeLoop(const int &pid, const int &timestamp,
+ const bool &valid);
void functionStatisticsAnalysis();
void timePairMatching();
@@ -122,6 +131,7 @@ public:
const std::unordered_map<int, std::unordered_map<int, TimePairInfo>> &
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<TraceLineReslove> &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 &timestamp)
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<int, FuncValid> 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 <vector>
// 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<int> traceLineIndex;
+ std::vector<bool> isRet;
+ std::vector<bool> valid; // rst
+
+ void addToVectors(int traceId, bool isR, bool val);
};
-class FirstInfo {
+class FuncStkValid {
public:
- std::vector<int> schedSwitchTime; // [coreId]
- std::vector<int> coreTime; // [coreId]
- int coreId; // first core in trace
- int startTime;
+ std::vector<int> funcStk;
+ std::vector<int> traceIndex;
+ std::vector<TRACE_VALID_E> 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<int, std::unordered_map<int, FuncValid>> funcPairMap;
+ // [pid] if funcstk have invalid data, mark all funcstk invalid
+ std::unordered_map<int, FuncStkValid> 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<TraceLineReslove> &getTraceLine() const;
- const FirstInfo &getTraceFirstInfo() const;
double convertTimeIntToDouble(const int &timestamp);
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 <duration> set tracing duration, unit: seconds, 1<=duration<=100, default is 10"
+ echo " -t <duration> 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