diff options
author | Kristof Beyls <kristof.beyls@arm.com> | 2018-05-23 12:56:57 +0000 |
---|---|---|
committer | Kristof Beyls <kristof.beyls@arm.com> | 2018-05-23 12:56:57 +0000 |
commit | c79e0ffd1cae3425de1a2349399148ab5163bd42 (patch) | |
tree | a4af38adaeac7d0a3ae186dd33d49fc89b4d1dcd | |
parent | 3b5ce906f5a8235719f4b793241436c16febc8c5 (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.cpp | 40 |
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 { |