summaryrefslogtreecommitdiff
path: root/Source/CTest/cmCTestMemCheckHandler.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/CTest/cmCTestMemCheckHandler.cxx')
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.cxx90
1 files changed, 68 insertions, 22 deletions
diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx
index b37db3003e..620e237248 100644
--- a/Source/CTest/cmCTestMemCheckHandler.cxx
+++ b/Source/CTest/cmCTestMemCheckHandler.cxx
@@ -127,6 +127,7 @@ void cmCTestMemCheckHandler::Initialize()
this->MemoryTesterOptions.clear();
this->MemoryTesterStyle = UNKNOWN;
this->MemoryTesterOutputFile = "";
+ this->DefectCount = 0;
}
int cmCTestMemCheckHandler::PreProcessHandler()
@@ -279,6 +280,11 @@ void cmCTestMemCheckHandler::PopulateCustomVectors(cmMakefile* mf)
this->Quiet);
}
+int cmCTestMemCheckHandler::GetDefectCount()
+{
+ return this->DefectCount;
+}
+
void cmCTestMemCheckHandler::GenerateDartOutput(cmXMLWriter& xml)
{
if (!this->CTest->GetProduceXML()) {
@@ -299,6 +305,9 @@ void cmCTestMemCheckHandler::GenerateDartOutput(cmXMLWriter& xml)
case cmCTestMemCheckHandler::ADDRESS_SANITIZER:
xml.Attribute("Checker", "AddressSanitizer");
break;
+ case cmCTestMemCheckHandler::LEAK_SANITIZER:
+ xml.Attribute("Checker", "LeakSanitizer");
+ break;
case cmCTestMemCheckHandler::THREAD_SANITIZER:
xml.Attribute("Checker", "ThreadSanitizer");
break;
@@ -323,10 +332,8 @@ void cmCTestMemCheckHandler::GenerateDartOutput(cmXMLWriter& xml)
}
xml.EndElement(); // TestList
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
- "-- Processing memory checking output: ", this->Quiet);
+ "-- Processing memory checking output:\n", this->Quiet);
size_t total = this->TestResults.size();
- size_t step = total / 10;
- size_t current = 0;
for (cc = 0; cc < this->TestResults.size(); cc++) {
cmCTestTestResult* result = &this->TestResults[cc];
std::string memcheckstr;
@@ -341,20 +348,31 @@ void cmCTestMemCheckHandler::GenerateDartOutput(cmXMLWriter& xml)
static_cast<size_t>(this->CustomMaximumFailedTestOutputSize));
this->WriteTestResultHeader(xml, result);
xml.StartElement("Results");
+ int memoryErrors = 0;
for (std::vector<int>::size_type kk = 0; kk < memcheckresults.size();
++kk) {
if (memcheckresults[kk]) {
xml.StartElement("Defect");
xml.Attribute("type", this->ResultStringsLong[kk]);
xml.Content(memcheckresults[kk]);
+ memoryErrors += memcheckresults[kk];
xml.EndElement(); // Defect
}
this->GlobalResults[kk] += memcheckresults[kk];
}
xml.EndElement(); // Results
-
+ if (memoryErrors > 0) {
+ const int maxTestNameWidth = this->CTest->GetMaxTestNameWidth();
+ std::string outname = result->Name + " ";
+ outname.resize(maxTestNameWidth + 4, '.');
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, cc + 1
+ << "/" << total << " MemCheck: #"
+ << result->TestCount << ": " << outname
+ << " Defects: " << memoryErrors << std::endl,
+ this->Quiet);
+ }
xml.StartElement("Log");
- if (this->CTest->ShouldCompressMemCheckOutput()) {
+ if (this->CTest->ShouldCompressTestOutput()) {
this->CTest->CompressString(memcheckstr);
xml.Attribute("compression", "gzip");
xml.Attribute("encoding", "base64");
@@ -363,23 +381,22 @@ void cmCTestMemCheckHandler::GenerateDartOutput(cmXMLWriter& xml)
xml.EndElement(); // Log
this->WriteTestResultFooter(xml, result);
- if (current < cc) {
- cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, "#" << std::flush,
- this->Quiet);
- current += step;
- }
}
- cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, std::endl, this->Quiet);
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+ "MemCheck log files can be found here: "
+ "( * corresponds to test number)"
+ << std::endl,
+ this->Quiet);
+ std::string output = this->MemoryTesterOutputFile;
+ cmSystemTools::ReplaceString(output, "??", "*");
+ cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT, output << std::endl,
+ this->Quiet);
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
"Memory checking results:" << std::endl, this->Quiet);
xml.StartElement("DefectList");
for (cc = 0; cc < this->GlobalResults.size(); cc++) {
if (this->GlobalResults[cc]) {
-#ifdef cerr
-#undef cerr
-#endif
std::cerr.width(35);
-#define cerr no_cerr
cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
this->ResultStringsLong[cc]
<< " - " << this->GlobalResults[cc] << std::endl,
@@ -445,6 +462,12 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
this->LogWithPID = true; // even if we give the log file the pid is added
}
if (this->CTest->GetCTestConfiguration("MemoryCheckType") ==
+ "LeakSanitizer") {
+ this->MemoryTester = this->CTest->GetCTestConfiguration("CMakeCommand");
+ this->MemoryTesterStyle = cmCTestMemCheckHandler::LEAK_SANITIZER;
+ this->LogWithPID = true; // even if we give the log file the pid is added
+ }
+ if (this->CTest->GetCTestConfiguration("MemoryCheckType") ==
"ThreadSanitizer") {
this->MemoryTester = this->CTest->GetCTestConfiguration("CMakeCommand");
this->MemoryTesterStyle = cmCTestMemCheckHandler::THREAD_SANITIZER;
@@ -572,6 +595,7 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
}
// these are almost the same but the env var used is different
case cmCTestMemCheckHandler::ADDRESS_SANITIZER:
+ case cmCTestMemCheckHandler::LEAK_SANITIZER:
case cmCTestMemCheckHandler::THREAD_SANITIZER:
case cmCTestMemCheckHandler::MEMORY_SANITIZER:
case cmCTestMemCheckHandler::UB_SANITIZER: {
@@ -583,12 +607,24 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
this->MemoryTesterDynamicOptions.push_back("-E");
this->MemoryTesterDynamicOptions.push_back("env");
std::string envVar;
- std::string extraOptions =
- this->CTest->GetCTestConfiguration("MemoryCheckSanitizerOptions");
+ std::string extraOptions;
+ std::string suppressionsOption;
+ if (!this->CTest->GetCTestConfiguration("MemoryCheckSanitizerOptions")
+ .empty()) {
+ extraOptions = ":" +
+ this->CTest->GetCTestConfiguration("MemoryCheckSanitizerOptions");
+ }
+ if (!this->CTest->GetCTestConfiguration("MemoryCheckSuppressionFile")
+ .empty()) {
+ suppressionsOption = ":suppressions=" +
+ this->CTest->GetCTestConfiguration("MemoryCheckSuppressionFile");
+ }
if (this->MemoryTesterStyle ==
cmCTestMemCheckHandler::ADDRESS_SANITIZER) {
envVar = "ASAN_OPTIONS";
- extraOptions += " detect_leaks=1";
+ } else if (this->MemoryTesterStyle ==
+ cmCTestMemCheckHandler::LEAK_SANITIZER) {
+ envVar = "LSAN_OPTIONS";
} else if (this->MemoryTesterStyle ==
cmCTestMemCheckHandler::THREAD_SANITIZER) {
envVar = "TSAN_OPTIONS";
@@ -599,9 +635,12 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
cmCTestMemCheckHandler::UB_SANITIZER) {
envVar = "UBSAN_OPTIONS";
}
+ // Quote log_path with single quotes; see
+ // https://bugs.chromium.org/p/chromium/issues/detail?id=467936
std::string outputFile =
- envVar + "=log_path=\"" + this->MemoryTesterOutputFile + "\" ";
- this->MemoryTesterEnvironmentVariable = outputFile + extraOptions;
+ envVar + "=log_path='" + this->MemoryTesterOutputFile + "'";
+ this->MemoryTesterEnvironmentVariable =
+ outputFile + suppressionsOption + extraOptions;
break;
}
default:
@@ -630,6 +669,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckOutput(const std::string& str,
case cmCTestMemCheckHandler::PURIFY:
return this->ProcessMemCheckPurifyOutput(str, log, results);
case cmCTestMemCheckHandler::ADDRESS_SANITIZER:
+ case cmCTestMemCheckHandler::LEAK_SANITIZER:
case cmCTestMemCheckHandler::THREAD_SANITIZER:
case cmCTestMemCheckHandler::MEMORY_SANITIZER:
case cmCTestMemCheckHandler::UB_SANITIZER:
@@ -666,6 +706,9 @@ bool cmCTestMemCheckHandler::ProcessMemCheckSanitizerOutput(
case cmCTestMemCheckHandler::ADDRESS_SANITIZER:
regex = "ERROR: AddressSanitizer: (.*) on.*";
break;
+ case cmCTestMemCheckHandler::LEAK_SANITIZER:
+ // use leakWarning regex
+ break;
case cmCTestMemCheckHandler::THREAD_SANITIZER:
regex = "WARNING: ThreadSanitizer: (.*) \\(pid=.*\\)";
break;
@@ -706,6 +749,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckSanitizerOutput(
ostr << *i << std::endl;
}
log = ostr.str();
+ this->DefectCount += defects;
return defects == 0;
}
bool cmCTestMemCheckHandler::ProcessMemCheckPurifyOutput(
@@ -747,6 +791,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckPurifyOutput(
}
log = ostr.str();
+ this->DefectCount += defects;
return defects == 0;
}
@@ -882,6 +927,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput(
<< (cmSystemTools::GetTime() - sttime) << std::endl,
this->Quiet);
log = ostr.str();
+ this->DefectCount += defects;
return defects == 0;
}
@@ -927,9 +973,9 @@ bool cmCTestMemCheckHandler::ProcessMemCheckBoundsCheckerOutput(
// only put the output of Bounds Checker if there were
// errors or leaks detected
log = parser.Log;
- return false;
}
- return true;
+ this->DefectCount += defects;
+ return defects == 0;
}
// PostProcessTest memcheck results