aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristof Beyls <kristof.beyls@arm.com>2018-05-23 12:56:57 +0000
committerKristof Beyls <kristof.beyls@arm.com>2018-05-23 12:56:57 +0000
commitc79e0ffd1cae3425de1a2349399148ab5163bd42 (patch)
treea4af38adaeac7d0a3ae186dd33d49fc89b4d1dcd
parent3b5ce906f5a8235719f4b793241436c16febc8c5 (diff)
lnt profile upgrade command for large Spec2017 perf.data aborts.
This patch addresses issue with *stack smashing* while processing large perf.data files (>350 MB) e.g. obtained during Spec2017 sub-benchmarks' runs: Example lnt profile upgrade failure: $ lnt profile upgrade perf.data.510.parest_r.0 perf.data.510.parest_r.0.lnt *** stack smashing detected ***: /opt/venv_lnt/bin/python terminated The arbitrary size of temp buffers One, Two, Three & Four in function NmOutput::fetchSymbols() is in some circumstances too small and buffer(s) overflow while processing line of data. This commit fixes that. Patch by Przemek Wirkus. Differential Revision: https://reviews.llvm.org/D46433 git-svn-id: https://llvm.org/svn/llvm-project/lnt/trunk@333081 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lnt/testing/profile/cPerf.cpp40
1 files changed, 27 insertions, 13 deletions
diff --git a/lnt/testing/profile/cPerf.cpp b/lnt/testing/profile/cPerf.cpp
index b24c637..838d38a 100644
--- a/lnt/testing/profile/cPerf.cpp
+++ b/lnt/testing/profile/cPerf.cpp
@@ -280,20 +280,25 @@ public:
if (Len == -1)
break;
- char One[32], Two[32], Three[32], Four[512];
- if (sscanf(Line, "%s %s %s %s", One, Two, Three, Four) < 4)
- continue;
+ std::vector<std::string> SplittedLine;
+ if (splitLine(std::string(Line), SplittedLine) < 4)
+ continue;
+
+ const std::string& One = SplittedLine[0];
+ const std::string& Two = SplittedLine[1];
+ const std::string& Three = SplittedLine[2];
+ std::string& Four = SplittedLine[3];
char *EndPtr = NULL;
- uint64_t Start = strtoull(One, &EndPtr, 16);
- if (EndPtr == One)
+ uint64_t Start = strtoull(One.c_str(), &EndPtr, 16);
+ if (EndPtr == One.c_str())
continue;
- uint64_t Extent = strtoull(Two, &EndPtr, 16);
- if (EndPtr == Two)
+ uint64_t Extent = strtoull(Two.c_str(), &EndPtr, 16);
+ if (EndPtr == Two.c_str())
continue;
- if (strlen(Three) != 1)
+ if (Three.length() != 1)
continue;
- switch (Three[0]) {
+ switch (Three.front()) {
default:
continue;
case 'T':
@@ -304,10 +309,9 @@ public:
case 'w': // Weak object (not tagged as such)
break;
}
- std::string S(Four);
- if (S.back() == '\n')
- S.pop_back();
- push_back({Start, Start + Extent, S});
+ if (Four.back() == '\n')
+ Four.pop_back();
+ push_back({Start, Start + Extent, Four});
}
if (Line)
free(Line);
@@ -326,6 +330,16 @@ public:
auto NewEnd = std::unique(begin(), end());
erase(NewEnd, end());
}
+
+protected:
+ int splitLine(const std::string& line, std::vector<std::string>& output, char delim = ' ') {
+ std::stringstream ss(line);
+ std::string token;
+ while (std::getline(ss, token, delim)) {
+ output.push_back(token);
+ }
+ return output.size();
+ }
};
class ObjdumpOutput {