Commit 3a523eec authored by Betsy McPhail's avatar Betsy McPhail Committed by Brad King

ctest_memcheck: Add DEFECT_COUNT option to capture defect count

parent 60d80bca
Pipeline #34675 passed with stage
...@@ -128,7 +128,7 @@ syn keyword cmakeKWctest_coverage ...@@ -128,7 +128,7 @@ syn keyword cmakeKWctest_coverage
\ contained \ contained
syn keyword cmakeKWctest_memcheck syn keyword cmakeKWctest_memcheck
\ APPEND BUILD END EXCLUDE EXCLUDE_LABEL INCLUDE INCLUDE_LABEL OFF ON PARALLEL_LEVEL QUIET RETURN_VALUE SCHEDULE_RANDOM START STOP_TIME STRIDE TEST_LOAD \ APPEND BUILD DEFECT_COUNT END EXCLUDE EXCLUDE_LABEL INCLUDE INCLUDE_LABEL OFF ON PARALLEL_LEVEL QUIET RETURN_VALUE SCHEDULE_RANDOM START STOP_TIME STRIDE TEST_LOAD
\ contained \ contained
syn keyword cmakeKWctest_run_script syn keyword cmakeKWctest_run_script
......
...@@ -18,6 +18,7 @@ Perform the :ref:`CTest MemCheck Step` as a :ref:`Dashboard Client`. ...@@ -18,6 +18,7 @@ Perform the :ref:`CTest MemCheck Step` as a :ref:`Dashboard Client`.
[SCHEDULE_RANDOM <ON|OFF>] [SCHEDULE_RANDOM <ON|OFF>]
[STOP_TIME <time-of-day>] [STOP_TIME <time-of-day>]
[RETURN_VALUE <result-var>] [RETURN_VALUE <result-var>]
[DEFECT_COUNT <defect-count-var>]
[QUIET] [QUIET]
) )
...@@ -26,4 +27,9 @@ Run tests with a dynamic analysis tool and store results in ...@@ -26,4 +27,9 @@ Run tests with a dynamic analysis tool and store results in
``MemCheck.xml`` for submission with the :command:`ctest_submit` ``MemCheck.xml`` for submission with the :command:`ctest_submit`
command. command.
The options are the same as those for the :command:`ctest_test` command. Most options are the same as those for the :command:`ctest_test` command.
The options unique to this command are:
``DEFECT_COUNT <defect-count-var>``
Store in the ``<defect-count-var>`` the number of defects found.
ctest_memcheck_defect_count
---------------------------
* The :command:`ctest_memcheck` command gained a ``DEFECT_COUNT <var>``
option to capture the number of memory defects detected.
...@@ -226,6 +226,7 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args, ...@@ -226,6 +226,7 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
this->Makefile->AddDefinition(this->Values[ct_RETURN_VALUE], this->Makefile->AddDefinition(this->Values[ct_RETURN_VALUE],
str.str().c_str()); str.str().c_str());
} }
this->ProcessAdditionalValues(handler);
// log the error message if there was an error // log the error message if there was an error
if (capureCMakeError) { if (capureCMakeError) {
const char* returnString = "0"; const char* returnString = "0";
...@@ -246,6 +247,10 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args, ...@@ -246,6 +247,10 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
return true; return true;
} }
void cmCTestHandlerCommand::ProcessAdditionalValues(cmCTestGenericHandler*)
{
}
bool cmCTestHandlerCommand::CheckArgumentKeyword(std::string const& arg) bool cmCTestHandlerCommand::CheckArgumentKeyword(std::string const& arg)
{ {
// Look for non-value arguments common to all commands. // Look for non-value arguments common to all commands.
......
...@@ -45,6 +45,8 @@ public: ...@@ -45,6 +45,8 @@ public:
protected: protected:
virtual cmCTestGenericHandler* InitializeHandler() = 0; virtual cmCTestGenericHandler* InitializeHandler() = 0;
virtual void ProcessAdditionalValues(cmCTestGenericHandler* handler);
// Command argument handling. // Command argument handling.
virtual bool CheckArgumentKeyword(std::string const& arg); virtual bool CheckArgumentKeyword(std::string const& arg);
virtual bool CheckArgumentValue(std::string const& arg); virtual bool CheckArgumentValue(std::string const& arg);
......
...@@ -4,6 +4,15 @@ ...@@ -4,6 +4,15 @@
#include "cmCTest.h" #include "cmCTest.h"
#include "cmCTestGenericHandler.h" #include "cmCTestGenericHandler.h"
#include "cmCTestMemCheckHandler.h"
#include "cmMakefile.h"
cmCTestMemCheckCommand::cmCTestMemCheckCommand()
{
this->Arguments[ctm_DEFECT_COUNT] = "DEFECT_COUNT";
this->Arguments[ctm_LAST] = CM_NULLPTR;
this->Last = ctm_LAST;
}
cmCTestGenericHandler* cmCTestMemCheckCommand::InitializeActualHandler() cmCTestGenericHandler* cmCTestMemCheckCommand::InitializeActualHandler()
{ {
...@@ -28,3 +37,14 @@ cmCTestGenericHandler* cmCTestMemCheckCommand::InitializeActualHandler() ...@@ -28,3 +37,14 @@ cmCTestGenericHandler* cmCTestMemCheckCommand::InitializeActualHandler()
handler->SetQuiet(this->Quiet); handler->SetQuiet(this->Quiet);
return handler; return handler;
} }
void cmCTestMemCheckCommand::ProcessAdditionalValues(
cmCTestGenericHandler* handler)
{
if (this->Values[ctm_DEFECT_COUNT] && *this->Values[ctm_DEFECT_COUNT]) {
std::ostringstream str;
str << static_cast<cmCTestMemCheckHandler*>(handler)->GetDefectCount();
this->Makefile->AddDefinition(this->Values[ctm_DEFECT_COUNT],
str.str().c_str());
}
}
...@@ -20,7 +20,7 @@ class cmCommand; ...@@ -20,7 +20,7 @@ class cmCommand;
class cmCTestMemCheckCommand : public cmCTestTestCommand class cmCTestMemCheckCommand : public cmCTestTestCommand
{ {
public: public:
cmCTestMemCheckCommand() {} cmCTestMemCheckCommand();
/** /**
* This is a virtual constructor for the command. * This is a virtual constructor for the command.
...@@ -40,6 +40,14 @@ public: ...@@ -40,6 +40,14 @@ public:
protected: protected:
cmCTestGenericHandler* InitializeActualHandler() CM_OVERRIDE; cmCTestGenericHandler* InitializeActualHandler() CM_OVERRIDE;
void ProcessAdditionalValues(cmCTestGenericHandler* handler) CM_OVERRIDE;
enum
{
ctm_DEFECT_COUNT = ctt_LAST,
ctm_LAST
};
}; };
#endif #endif
...@@ -127,6 +127,7 @@ void cmCTestMemCheckHandler::Initialize() ...@@ -127,6 +127,7 @@ void cmCTestMemCheckHandler::Initialize()
this->MemoryTesterOptions.clear(); this->MemoryTesterOptions.clear();
this->MemoryTesterStyle = UNKNOWN; this->MemoryTesterStyle = UNKNOWN;
this->MemoryTesterOutputFile = ""; this->MemoryTesterOutputFile = "";
this->DefectCount = 0;
} }
int cmCTestMemCheckHandler::PreProcessHandler() int cmCTestMemCheckHandler::PreProcessHandler()
...@@ -279,6 +280,11 @@ void cmCTestMemCheckHandler::PopulateCustomVectors(cmMakefile* mf) ...@@ -279,6 +280,11 @@ void cmCTestMemCheckHandler::PopulateCustomVectors(cmMakefile* mf)
this->Quiet); this->Quiet);
} }
int cmCTestMemCheckHandler::GetDefectCount()
{
return this->DefectCount;
}
void cmCTestMemCheckHandler::GenerateDartOutput(cmXMLWriter& xml) void cmCTestMemCheckHandler::GenerateDartOutput(cmXMLWriter& xml)
{ {
if (!this->CTest->GetProduceXML()) { if (!this->CTest->GetProduceXML()) {
...@@ -702,6 +708,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckSanitizerOutput( ...@@ -702,6 +708,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckSanitizerOutput(
ostr << *i << std::endl; ostr << *i << std::endl;
} }
log = ostr.str(); log = ostr.str();
this->DefectCount += defects;
return defects == 0; return defects == 0;
} }
bool cmCTestMemCheckHandler::ProcessMemCheckPurifyOutput( bool cmCTestMemCheckHandler::ProcessMemCheckPurifyOutput(
...@@ -743,6 +750,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckPurifyOutput( ...@@ -743,6 +750,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckPurifyOutput(
} }
log = ostr.str(); log = ostr.str();
this->DefectCount += defects;
return defects == 0; return defects == 0;
} }
...@@ -878,6 +886,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput( ...@@ -878,6 +886,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput(
<< (cmSystemTools::GetTime() - sttime) << std::endl, << (cmSystemTools::GetTime() - sttime) << std::endl,
this->Quiet); this->Quiet);
log = ostr.str(); log = ostr.str();
this->DefectCount += defects;
return defects == 0; return defects == 0;
} }
...@@ -923,9 +932,9 @@ bool cmCTestMemCheckHandler::ProcessMemCheckBoundsCheckerOutput( ...@@ -923,9 +932,9 @@ bool cmCTestMemCheckHandler::ProcessMemCheckBoundsCheckerOutput(
// only put the output of Bounds Checker if there were // only put the output of Bounds Checker if there were
// errors or leaks detected // errors or leaks detected
log = parser.Log; log = parser.Log;
return false;
} }
return true; this->DefectCount += defects;
return defects == 0;
} }
// PostProcessTest memcheck results // PostProcessTest memcheck results
......
...@@ -30,6 +30,8 @@ public: ...@@ -30,6 +30,8 @@ public:
void Initialize() CM_OVERRIDE; void Initialize() CM_OVERRIDE;
int GetDefectCount();
protected: protected:
int PreProcessHandler() CM_OVERRIDE; int PreProcessHandler() CM_OVERRIDE;
int PostProcessHandler() CM_OVERRIDE; int PostProcessHandler() CM_OVERRIDE;
...@@ -105,6 +107,7 @@ private: ...@@ -105,6 +107,7 @@ private:
std::vector<std::string> ResultStringsLong; std::vector<std::string> ResultStringsLong;
std::vector<int> GlobalResults; std::vector<int> GlobalResults;
bool LogWithPID; // does log file add pid bool LogWithPID; // does log file add pid
int DefectCount;
std::vector<int>::size_type FindOrAddWarning(const std::string& warning); std::vector<int>::size_type FindOrAddWarning(const std::string& warning);
// initialize the ResultStrings and ResultStringsLong for // initialize the ResultStrings and ResultStringsLong for
......
Memory checking results:
Direct leak - 2
Indirect leak - 1
1/1 MemCheck #1: RunCMake \.+ Passed +[0-9]+.[0-9]+ sec
100% tests passed, 0 tests failed out of 1
.*
-- Processing memory checking output:( )
Memory checking results:
...@@ -12,6 +12,8 @@ endfunction() ...@@ -12,6 +12,8 @@ endfunction()
unset(CTEST_EXTRA_CONFIG) unset(CTEST_EXTRA_CONFIG)
unset(CTEST_EXTRA_CODE) unset(CTEST_EXTRA_CODE)
unset(CTEST_SUFFIX_CODE)
unset(CTEST_MEMCHECK_ARGS)
unset(CMAKELISTS_EXTRA_CODE) unset(CMAKELISTS_EXTRA_CODE)
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
...@@ -132,4 +134,31 @@ run_mc_test(DummyValgrindNoLogFile "${PSEUDO_VALGRIND_NOLOG}") ...@@ -132,4 +134,31 @@ run_mc_test(DummyValgrindNoLogFile "${PSEUDO_VALGRIND_NOLOG}")
run_mc_test(DummyBCNoLogFile "${PSEUDO_BC_NOLOG}") run_mc_test(DummyBCNoLogFile "${PSEUDO_BC_NOLOG}")
run_mc_test(NotExist "\${CTEST_BINARY_DIRECTORY}/no-memcheck-exe") run_mc_test(NotExist "\${CTEST_BINARY_DIRECTORY}/no-memcheck-exe")
run_mc_test(Unknown "\${CMAKE_COMMAND}") run_mc_test(Unknown "\${CMAKE_COMMAND}")
run_mc_test(DummyQuiet "${PSEUDO_VALGRIND}" -DMEMCHECK_ARGS=QUIET)
#----------------------------------------------------------------------------
set(CTEST_MEMCHECK_ARGS QUIET)
run_mc_test(DummyQuiet "${PSEUDO_VALGRIND}")
unset(CTEST_MEMCHECK_ARGS)
#-----------------------------------------------------------------------------
set(CTEST_SUFFIX_CODE "message(\"Defect count: \${defect_count}\")")
set(CTEST_MEMCHECK_ARGS "DEFECT_COUNT defect_count")
run_mc_test(DummyValgrindNoDefects "${PSEUDO_VALGRIND}")
unset(CTEST_MEMCHECK_ARGS)
unset(CTEST_SUFFIX_CODE)
#-----------------------------------------------------------------------------
set(CTEST_SUFFIX_CODE "message(\"Defect count: \${defect_count}\")")
set(CTEST_MEMCHECK_ARGS "DEFECT_COUNT defect_count")
set(CTEST_EXTRA_CODE
"set(CTEST_MEMORYCHECK_SANITIZER_OPTIONS \"simulate_sanitizer=1 report_bugs=1 history_size=5 exitcode=55\")
")
set(CMAKELISTS_EXTRA_CODE
"add_test(NAME TestSan COMMAND \"${CMAKE_COMMAND}\"
-P \"${RunCMake_SOURCE_DIR}/testLeakSanitizer.cmake\")
")
run_mc_test(DummyLeakSanitizerPrintDefects "" -DMEMCHECK_TYPE=AddressSanitizer)
unset(CMAKELISTS_EXTRA_CODE)
unset(CTEST_EXTRA_CODE)
unset(CTEST_MEMCHECK_ARGS)
unset(CTEST_SUFFIX_CODE)
...@@ -21,4 +21,6 @@ set(CTEST_MEMORYCHECK_TYPE "${MEMCHECK_TYPE}") ...@@ -21,4 +21,6 @@ set(CTEST_MEMORYCHECK_TYPE "${MEMCHECK_TYPE}")
CTEST_START(Experimental) CTEST_START(Experimental)
CTEST_CONFIGURE(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res) CTEST_CONFIGURE(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res) CTEST_TEST(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res)
CTEST_MEMCHECK(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res ${MEMCHECK_ARGS}) CTEST_MEMCHECK(BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res @CTEST_MEMCHECK_ARGS@)
@CTEST_SUFFIX_CODE@
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment