Merge topic 'parallel-memcheck'
6f9aaad
CTest: create one output file per memcheck (#14303)
This commit is contained in:
commit
d422ee362d
|
@ -89,7 +89,7 @@ void cmCTestBatchTestHandler::WriteTestCommand(int test, std::fstream& fout)
|
|||
command = cmSystemTools::ConvertToOutputPath(command.c_str());
|
||||
|
||||
//Prepends memcheck args to our command string if this is a memcheck
|
||||
this->TestHandler->GenerateTestCommand(processArgs);
|
||||
this->TestHandler->GenerateTestCommand(processArgs, test);
|
||||
processArgs.push_back(command);
|
||||
|
||||
for(std::vector<std::string>::iterator arg = processArgs.begin();
|
||||
|
|
|
@ -200,6 +200,7 @@ void cmCTestMemCheckHandler::Initialize()
|
|||
this->CustomMaximumPassedTestOutputSize = 0;
|
||||
this->CustomMaximumFailedTestOutputSize = 0;
|
||||
this->MemoryTester = "";
|
||||
this->MemoryTesterDynamicOptions.clear();
|
||||
this->MemoryTesterOptions.clear();
|
||||
this->MemoryTesterStyle = UNKNOWN;
|
||||
this->MemoryTesterOutputFile = "";
|
||||
|
@ -242,12 +243,28 @@ int cmCTestMemCheckHandler::PostProcessHandler()
|
|||
|
||||
//----------------------------------------------------------------------
|
||||
void cmCTestMemCheckHandler::GenerateTestCommand(
|
||||
std::vector<std::string>& args)
|
||||
std::vector<std::string>& args, int test)
|
||||
{
|
||||
std::vector<cmStdString>::size_type pp;
|
||||
std::string memcheckcommand = "";
|
||||
memcheckcommand
|
||||
cmStdString index;
|
||||
cmOStringStream stream;
|
||||
std::string memcheckcommand
|
||||
= cmSystemTools::ConvertToOutputPath(this->MemoryTester.c_str());
|
||||
stream << test;
|
||||
index = stream.str();
|
||||
for ( pp = 0; pp < this->MemoryTesterDynamicOptions.size(); pp ++ )
|
||||
{
|
||||
cmStdString arg = this->MemoryTesterDynamicOptions[pp];
|
||||
cmStdString::size_type pos = arg.find("??");
|
||||
if (pos != cmStdString::npos)
|
||||
{
|
||||
arg.replace(pos, 2, index);
|
||||
}
|
||||
args.push_back(arg);
|
||||
memcheckcommand += " \"";
|
||||
memcheckcommand += arg;
|
||||
memcheckcommand += "\"";
|
||||
}
|
||||
for ( pp = 0; pp < this->MemoryTesterOptions.size(); pp ++ )
|
||||
{
|
||||
args.push_back(this->MemoryTesterOptions[pp]);
|
||||
|
@ -478,7 +495,8 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
|
|||
= cmSystemTools::ParseArguments(memoryTesterOptions.c_str());
|
||||
|
||||
this->MemoryTesterOutputFile
|
||||
= this->CTest->GetBinaryDir() + "/Testing/Temporary/MemoryChecker.log";
|
||||
= this->CTest->GetBinaryDir()
|
||||
+ "/Testing/Temporary/MemoryChecker.??.log";
|
||||
|
||||
switch ( this->MemoryTesterStyle )
|
||||
{
|
||||
|
@ -510,7 +528,7 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
|
|||
}
|
||||
std::string outputFile = "--log-file="
|
||||
+ this->MemoryTesterOutputFile;
|
||||
this->MemoryTesterOptions.push_back(outputFile);
|
||||
this->MemoryTesterDynamicOptions.push_back(outputFile);
|
||||
break;
|
||||
}
|
||||
case cmCTestMemCheckHandler::PURIFY:
|
||||
|
@ -538,19 +556,19 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
|
|||
outputFile = "-log-file=";
|
||||
#endif
|
||||
outputFile += this->MemoryTesterOutputFile;
|
||||
this->MemoryTesterOptions.push_back(outputFile);
|
||||
this->MemoryTesterDynamicOptions.push_back(outputFile);
|
||||
break;
|
||||
}
|
||||
case cmCTestMemCheckHandler::BOUNDS_CHECKER:
|
||||
{
|
||||
this->BoundsCheckerXMLFile = this->MemoryTesterOutputFile;
|
||||
std::string dpbdFile = this->CTest->GetBinaryDir()
|
||||
+ "/Testing/Temporary/MemoryChecker.DPbd";
|
||||
+ "/Testing/Temporary/MemoryChecker.??.DPbd";
|
||||
this->BoundsCheckerDPBDFile = dpbdFile;
|
||||
this->MemoryTesterOptions.push_back("/B");
|
||||
this->MemoryTesterOptions.push_back(dpbdFile);
|
||||
this->MemoryTesterOptions.push_back("/X");
|
||||
this->MemoryTesterOptions.push_back(this->MemoryTesterOutputFile);
|
||||
this->MemoryTesterDynamicOptions.push_back("/B");
|
||||
this->MemoryTesterDynamicOptions.push_back(dpbdFile);
|
||||
this->MemoryTesterDynamicOptions.push_back("/X");
|
||||
this->MemoryTesterDynamicOptions.push_back(this->MemoryTesterOutputFile);
|
||||
this->MemoryTesterOptions.push_back("/M");
|
||||
break;
|
||||
}
|
||||
|
@ -898,25 +916,23 @@ bool cmCTestMemCheckHandler::ProcessMemCheckBoundsCheckerOutput(
|
|||
// This method puts the bounds checker output file into the output
|
||||
// for the test
|
||||
void
|
||||
cmCTestMemCheckHandler::PostProcessBoundsCheckerTest(cmCTestTestResult& res)
|
||||
cmCTestMemCheckHandler::PostProcessBoundsCheckerTest(cmCTestTestResult& res,
|
||||
int test)
|
||||
{
|
||||
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
|
||||
"PostProcessBoundsCheckerTest for : "
|
||||
<< res.Name.c_str() << std::endl);
|
||||
if ( !cmSystemTools::FileExists(this->MemoryTesterOutputFile.c_str()) )
|
||||
cmStdString ofile = testOutputFileName(test);
|
||||
if ( ofile.empty() )
|
||||
{
|
||||
std::string log = "Cannot find memory tester output file: "
|
||||
+ this->MemoryTesterOutputFile;
|
||||
cmCTestLog(this->CTest, ERROR_MESSAGE, log.c_str() << std::endl);
|
||||
return;
|
||||
}
|
||||
// put a scope around this to close ifs so the file can be removed
|
||||
{
|
||||
std::ifstream ifs(this->MemoryTesterOutputFile.c_str());
|
||||
std::ifstream ifs(ofile.c_str());
|
||||
if ( !ifs )
|
||||
{
|
||||
std::string log = "Cannot read memory tester output file: "
|
||||
+ this->MemoryTesterOutputFile;
|
||||
std::string log = "Cannot read memory tester output file: " + ofile;
|
||||
cmCTestLog(this->CTest, ERROR_MESSAGE, log.c_str() << std::endl);
|
||||
return;
|
||||
}
|
||||
|
@ -939,38 +955,39 @@ cmCTestMemCheckHandler::PostProcessBoundsCheckerTest(cmCTestTestResult& res)
|
|||
}
|
||||
|
||||
void
|
||||
cmCTestMemCheckHandler::PostProcessPurifyTest(cmCTestTestResult& res)
|
||||
cmCTestMemCheckHandler::PostProcessPurifyTest(cmCTestTestResult& res,
|
||||
int test)
|
||||
{
|
||||
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
|
||||
"PostProcessPurifyTest for : "
|
||||
<< res.Name.c_str() << std::endl);
|
||||
appendMemTesterOutput(res);
|
||||
appendMemTesterOutput(res, test);
|
||||
}
|
||||
|
||||
void
|
||||
cmCTestMemCheckHandler::PostProcessValgrindTest(cmCTestTestResult& res)
|
||||
cmCTestMemCheckHandler::PostProcessValgrindTest(cmCTestTestResult& res,
|
||||
int test)
|
||||
{
|
||||
cmCTestLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
|
||||
"PostProcessValgrindTest for : "
|
||||
<< res.Name.c_str() << std::endl);
|
||||
appendMemTesterOutput(res);
|
||||
appendMemTesterOutput(res, test);
|
||||
}
|
||||
|
||||
void
|
||||
cmCTestMemCheckHandler::appendMemTesterOutput(cmCTestTestResult& res)
|
||||
cmCTestMemCheckHandler::appendMemTesterOutput(cmCTestTestResult& res,
|
||||
int test)
|
||||
{
|
||||
if ( !cmSystemTools::FileExists(this->MemoryTesterOutputFile.c_str()) )
|
||||
cmStdString ofile = testOutputFileName(test);
|
||||
|
||||
if ( ofile.empty() )
|
||||
{
|
||||
std::string log = "Cannot find memory tester output file: "
|
||||
+ this->MemoryTesterOutputFile;
|
||||
cmCTestLog(this->CTest, ERROR_MESSAGE, log.c_str() << std::endl);
|
||||
return;
|
||||
}
|
||||
std::ifstream ifs(this->MemoryTesterOutputFile.c_str());
|
||||
std::ifstream ifs(ofile.c_str());
|
||||
if ( !ifs )
|
||||
{
|
||||
std::string log = "Cannot read memory tester output file: "
|
||||
+ this->MemoryTesterOutputFile;
|
||||
std::string log = "Cannot read memory tester output file: " + ofile;
|
||||
cmCTestLog(this->CTest, ERROR_MESSAGE, log.c_str() << std::endl);
|
||||
return;
|
||||
}
|
||||
|
@ -981,3 +998,25 @@ cmCTestMemCheckHandler::appendMemTesterOutput(cmCTestTestResult& res)
|
|||
res.Output += "\n";
|
||||
}
|
||||
}
|
||||
|
||||
cmStdString
|
||||
cmCTestMemCheckHandler::testOutputFileName(int test)
|
||||
{
|
||||
cmStdString index;
|
||||
cmOStringStream stream;
|
||||
stream << test;
|
||||
index = stream.str();
|
||||
cmStdString ofile = this->MemoryTesterOutputFile;
|
||||
cmStdString::size_type pos = ofile.find("??");
|
||||
ofile.replace(pos, 2, index);
|
||||
|
||||
if ( !cmSystemTools::FileExists(ofile.c_str()) )
|
||||
{
|
||||
std::string log = "Cannot find memory tester output file: "
|
||||
+ ofile;
|
||||
cmCTestLog(this->CTest, ERROR_MESSAGE, log.c_str() << std::endl);
|
||||
ofile = "";
|
||||
}
|
||||
|
||||
return ofile;
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ public:
|
|||
protected:
|
||||
virtual int PreProcessHandler();
|
||||
virtual int PostProcessHandler();
|
||||
virtual void GenerateTestCommand(std::vector<std::string>& args);
|
||||
virtual void GenerateTestCommand(std::vector<std::string>& args, int test);
|
||||
|
||||
private:
|
||||
|
||||
|
@ -89,6 +89,7 @@ private:
|
|||
std::string BoundsCheckerDPBDFile;
|
||||
std::string BoundsCheckerXMLFile;
|
||||
std::string MemoryTester;
|
||||
std::vector<cmStdString> MemoryTesterDynamicOptions;
|
||||
std::vector<cmStdString> MemoryTesterOptions;
|
||||
int MemoryTesterStyle;
|
||||
std::string MemoryTesterOutputFile;
|
||||
|
@ -117,12 +118,16 @@ private:
|
|||
bool ProcessMemCheckBoundsCheckerOutput(const std::string& str,
|
||||
std::string& log, int* results);
|
||||
|
||||
void PostProcessPurifyTest(cmCTestTestResult& res);
|
||||
void PostProcessBoundsCheckerTest(cmCTestTestResult& res);
|
||||
void PostProcessValgrindTest(cmCTestTestResult& res);
|
||||
void PostProcessPurifyTest(cmCTestTestResult& res, int test);
|
||||
void PostProcessBoundsCheckerTest(cmCTestTestResult& res, int test);
|
||||
void PostProcessValgrindTest(cmCTestTestResult& res, int test);
|
||||
|
||||
///! append MemoryTesterOutputFile to the test log
|
||||
void appendMemTesterOutput(cmCTestTestHandler::cmCTestTestResult& res);
|
||||
void appendMemTesterOutput(cmCTestTestHandler::cmCTestTestResult& res,
|
||||
int test);
|
||||
|
||||
///! generate the output filename for the given test index
|
||||
cmStdString testOutputFileName(int test);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -389,13 +389,13 @@ void cmCTestRunTest::MemCheckPostProcess()
|
|||
switch ( handler->MemoryTesterStyle )
|
||||
{
|
||||
case cmCTestMemCheckHandler::VALGRIND:
|
||||
handler->PostProcessValgrindTest(this->TestResult);
|
||||
handler->PostProcessValgrindTest(this->TestResult, this->Index);
|
||||
break;
|
||||
case cmCTestMemCheckHandler::PURIFY:
|
||||
handler->PostProcessPurifyTest(this->TestResult);
|
||||
handler->PostProcessPurifyTest(this->TestResult, this->Index);
|
||||
break;
|
||||
case cmCTestMemCheckHandler::BOUNDS_CHECKER:
|
||||
handler->PostProcessBoundsCheckerTest(this->TestResult);
|
||||
handler->PostProcessBoundsCheckerTest(this->TestResult, this->Index);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -524,7 +524,7 @@ void cmCTestRunTest::ComputeArguments()
|
|||
= cmSystemTools::ConvertToOutputPath(this->ActualCommand.c_str());
|
||||
|
||||
//Prepends memcheck args to our command string
|
||||
this->TestHandler->GenerateTestCommand(this->Arguments);
|
||||
this->TestHandler->GenerateTestCommand(this->Arguments, this->Index);
|
||||
for(std::vector<std::string>::iterator i = this->Arguments.begin();
|
||||
i != this->Arguments.end(); ++i)
|
||||
{
|
||||
|
|
|
@ -1107,7 +1107,7 @@ void cmCTestTestHandler::ProcessDirectory(std::vector<cmStdString> &passed,
|
|||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void cmCTestTestHandler::GenerateTestCommand(std::vector<std::string>&)
|
||||
void cmCTestTestHandler::GenerateTestCommand(std::vector<std::string>&, int)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -153,7 +153,7 @@ protected:
|
|||
// compute a final test list
|
||||
virtual int PreProcessHandler();
|
||||
virtual int PostProcessHandler();
|
||||
virtual void GenerateTestCommand(std::vector<std::string>& args);
|
||||
virtual void GenerateTestCommand(std::vector<std::string>& args, int test);
|
||||
int ExecuteCommands(std::vector<cmStdString>& vec);
|
||||
|
||||
void WriteTestResultHeader(std::ostream& os, cmCTestTestResult* result);
|
||||
|
|
|
@ -66,6 +66,7 @@ function(gen_mc_test NAME CHECKER)
|
|||
-D PSEUDO_PURIFY=$<TARGET_FILE:pseudo_purify>
|
||||
-D PSEUDO_VALGRIND=$<TARGET_FILE:pseudo_valgrind>
|
||||
-D ERROR_COMMAND=$<TARGET_FILE:memcheck_fail>
|
||||
${ARGN}
|
||||
)
|
||||
endfunction(gen_mc_test)
|
||||
|
||||
|
@ -74,10 +75,11 @@ function(gen_mcnl_test NAME CHECKER)
|
|||
-D PSEUDO_BC=$<TARGET_FILE:pseudonl_BC>
|
||||
-D PSEUDO_PURIFY=$<TARGET_FILE:pseudonl_purify>
|
||||
-D PSEUDO_VALGRIND=$<TARGET_FILE:pseudonl_valgrind>
|
||||
${ARGN}
|
||||
)
|
||||
set_tests_properties(CTestTestMemcheck${NAME}
|
||||
PROPERTIES
|
||||
PASS_REGULAR_EXPRESSION "\nCannot find memory tester output file: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/${NAME}/Testing/Temporary/MemoryChecker.log\n(.*\n)?Error in read script: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/${NAME}/test.cmake\n")
|
||||
PASS_REGULAR_EXPRESSION "\nCannot find memory tester output file: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/${NAME}/Testing/Temporary/MemoryChecker.1.log\n(.*\n)?Error in read script: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/${NAME}/test.cmake\n")
|
||||
endfunction(gen_mcnl_test)
|
||||
|
||||
unset(CTEST_EXTRA_CONFIG)
|
||||
|
@ -109,14 +111,17 @@ set(CTEST_EXTRA_CONFIG "set(CTEST_CUSTOM_MEMCHECK_IGNORE RunCMakeAgain)\n")
|
|||
set(CMAKELISTS_EXTRA_CODE "add_test(NAME RunCMakeAgain COMMAND \"\${CMAKE_COMMAND}\" --version)")
|
||||
gen_mc_test(DummyValgrindIgnoreMemcheck "\${PSEUDO_VALGRIND}")
|
||||
|
||||
unset(CTEST_EXTRA_CONFIG)
|
||||
gen_mc_test(DummyValgrindTwoTargets "\${PSEUDO_VALGRIND}" "-VV")
|
||||
|
||||
set(CTEST_EXTRA_CONFIG "set(CTEST_MEMORYCHECK_SUPPRESSIONS_FILE \"\${CMAKE_CURRENT_BINARY_DIR}/does-not-exist\")")
|
||||
unset(CMAKELISTS_EXTRA_CODE)
|
||||
gen_mc_test(DummyValgrindInvalidSupFile "\${PSEUDO_VALGRIND}")
|
||||
|
||||
# CTest will add the logfile option as last option. Tell the dummy memcheck
|
||||
# to ignore that argument. This will cause the logfile to be missing, which
|
||||
# will be the prove for us that the custom option is indeed used.
|
||||
set(CTEST_EXTRA_CONFIG "set(CTEST_MEMORYCHECK_COMMAND_OPTIONS \"--\")")
|
||||
# CTest will add the logfile option before any custom options. Set the logfile
|
||||
# again, this time to an empty string. This will cause the logfile to be
|
||||
# missing, which will be the prove for us that the custom option is indeed used.
|
||||
set(CTEST_EXTRA_CONFIG "set(CTEST_MEMORYCHECK_COMMAND_OPTIONS \"--log-file=\")")
|
||||
gen_mc_test(DummyValgrindCustomOptions "\${PSEUDO_VALGRIND}")
|
||||
|
||||
unset(CTEST_EXTRA_CONFIG)
|
||||
|
@ -161,4 +166,8 @@ set_tests_properties(CTestTestMemcheckDummyValgrindInvalidSupFile PROPERTIES
|
|||
PASS_REGULAR_EXPRESSION "\nCannot find memory checker suppression file: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/does-not-exist\n")
|
||||
|
||||
set_tests_properties(CTestTestMemcheckDummyValgrindCustomOptions PROPERTIES
|
||||
PASS_REGULAR_EXPRESSION "\nCannot find memory tester output file: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindCustomOptions/Testing/Temporary/MemoryChecker.log\n(.*\n)?Error in read script: ${CMAKE_CURRENT_BINARY_DIR}/DummyValgrindCustomOptions/test.cmake\n")
|
||||
PASS_REGULAR_EXPRESSION "\nCannot find memory tester output file: ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindCustomOptions/Testing/Temporary/MemoryChecker.1.log\n(.*\n)?Error in read script: ${CMAKE_CURRENT_BINARY_DIR}/DummyValgrindCustomOptions/test.cmake\n")
|
||||
|
||||
set_tests_properties(CTestTestMemcheckDummyValgrindTwoTargets PROPERTIES
|
||||
PASS_REGULAR_EXPRESSION
|
||||
"\nMemory check project ${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindTwoTargets\n.*\n *Start 1: RunCMake\n(.*\n)?Memory check command: .* \"--log-file=${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindTwoTargets/Testing/Temporary/MemoryChecker.1.log\" \"-q\".*\n *Start 2: RunCMakeAgain\n(.*\n)?Memory check command: .* \"--log-file=${CTEST_ESCAPED_CMAKE_CURRENT_BINARY_DIR}/DummyValgrindTwoTargets/Testing/Temporary/MemoryChecker.2.log\" \"-q\".*\n")
|
||||
|
|
|
@ -28,12 +28,6 @@ main(int argc, char **argv)
|
|||
std::string logfile;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
std::string arg = argv[i];
|
||||
// stop processing options, this allows to force
|
||||
// the logfile to be ignored
|
||||
if (arg == "--")
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (arg.find(logarg) == 0)
|
||||
{
|
||||
if (nextarg)
|
||||
|
@ -46,7 +40,7 @@ main(int argc, char **argv)
|
|||
{
|
||||
logfile = arg.substr(logarg.length());
|
||||
}
|
||||
break;
|
||||
// keep searching, it may be overridden later to provoke an error
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue