summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Auxiliary/vim/syntax/cmake.vim2
-rw-r--r--Help/command/ctest_memcheck.rst8
-rw-r--r--Help/release/dev/ctest_memcheck_defect_count.rst5
-rw-r--r--Source/CTest/cmCTestHandlerCommand.cxx5
-rw-r--r--Source/CTest/cmCTestHandlerCommand.h2
-rw-r--r--Source/CTest/cmCTestMemCheckCommand.cxx20
-rw-r--r--Source/CTest/cmCTestMemCheckCommand.h10
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.cxx13
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.h3
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyLeakSanitizerPrintDefects-result.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyLeakSanitizerPrintDefects-stderr.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyLeakSanitizerPrintDefects-stdout.txt3
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyValgrindNoDefects-result.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyValgrindNoDefects-stderr.txt1
-rw-r--r--Tests/RunCMake/ctest_memcheck/DummyValgrindNoDefects-stdout.txt6
-rw-r--r--Tests/RunCMake/ctest_memcheck/RunCMakeTest.cmake31
-rw-r--r--Tests/RunCMake/ctest_memcheck/test.cmake.in4
17 files changed, 109 insertions, 7 deletions
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim
index 11b0fcb..fabf9c1 100644
--- a/Auxiliary/vim/syntax/cmake.vim
+++ b/Auxiliary/vim/syntax/cmake.vim
@@ -128,7 +128,7 @@ syn keyword cmakeKWctest_coverage
\ contained
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
syn keyword cmakeKWctest_run_script
diff --git a/Help/command/ctest_memcheck.rst b/Help/command/ctest_memcheck.rst
index 29bdf7d..a983d68 100644
--- a/Help/command/ctest_memcheck.rst
+++ b/Help/command/ctest_memcheck.rst
@@ -18,6 +18,7 @@ Perform the :ref:`CTest MemCheck Step` as a :ref:`Dashboard Client`.
[SCHEDULE_RANDOM <ON|OFF>]
[STOP_TIME <time-of-day>]
[RETURN_VALUE <result-var>]
+ [DEFECT_COUNT <defect-count-var>]
[QUIET]
)
@@ -26,4 +27,9 @@ Run tests with a dynamic analysis tool and store results in
``MemCheck.xml`` for submission with the :command:`ctest_submit`
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.
diff --git a/Help/release/dev/ctest_memcheck_defect_count.rst b/Help/release/dev/ctest_memcheck_defect_count.rst
new file mode 100644
index 0000000..70061c1
--- /dev/null
+++ b/Help/release/dev/ctest_memcheck_defect_count.rst
@@ -0,0 +1,5 @@
+ctest_memcheck_defect_count
+---------------------------
+
+* The :command:`ctest_memcheck` command gained a ``DEFECT_COUNT <var>``
+ option to capture the number of memory defects detected.
diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx
index 2e5b56a..a989b12 100644
--- a/Source/CTest/cmCTestHandlerCommand.cxx
+++ b/Source/CTest/cmCTestHandlerCommand.cxx
@@ -226,6 +226,7 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
this->Makefile->AddDefinition(this->Values[ct_RETURN_VALUE],
str.str().c_str());
}
+ this->ProcessAdditionalValues(handler);
// log the error message if there was an error
if (capureCMakeError) {
const char* returnString = "0";
@@ -246,6 +247,10 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
return true;
}
+void cmCTestHandlerCommand::ProcessAdditionalValues(cmCTestGenericHandler*)
+{
+}
+
bool cmCTestHandlerCommand::CheckArgumentKeyword(std::string const& arg)
{
// Look for non-value arguments common to all commands.
diff --git a/Source/CTest/cmCTestHandlerCommand.h b/Source/CTest/cmCTestHandlerCommand.h
index 92748af..c86841f 100644
--- a/Source/CTest/cmCTestHandlerCommand.h
+++ b/Source/CTest/cmCTestHandlerCommand.h
@@ -45,6 +45,8 @@ public:
protected:
virtual cmCTestGenericHandler* InitializeHandler() = 0;
+ virtual void ProcessAdditionalValues(cmCTestGenericHandler* handler);
+
// Command argument handling.
virtual bool CheckArgumentKeyword(std::string const& arg);
virtual bool CheckArgumentValue(std::string const& arg);
diff --git a/Source/CTest/cmCTestMemCheckCommand.cxx b/Source/CTest/cmCTestMemCheckCommand.cxx
index 05d0a53..5e4c5ae 100644
--- a/Source/CTest/cmCTestMemCheckCommand.cxx
+++ b/Source/CTest/cmCTestMemCheckCommand.cxx
@@ -4,6 +4,15 @@
#include "cmCTest.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()
{
@@ -28,3 +37,14 @@ cmCTestGenericHandler* cmCTestMemCheckCommand::InitializeActualHandler()
handler->SetQuiet(this->Quiet);
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());
+ }
+}
diff --git a/Source/CTest/cmCTestMemCheckCommand.h b/Source/CTest/cmCTestMemCheckCommand.h
index 30d9e2b..458ebb0 100644
--- a/Source/CTest/cmCTestMemCheckCommand.h
+++ b/Source/CTest/cmCTestMemCheckCommand.h
@@ -20,7 +20,7 @@ class cmCommand;
class cmCTestMemCheckCommand : public cmCTestTestCommand
{
public:
- cmCTestMemCheckCommand() {}
+ cmCTestMemCheckCommand();
/**
* This is a virtual constructor for the command.
@@ -40,6 +40,14 @@ public:
protected:
cmCTestGenericHandler* InitializeActualHandler() CM_OVERRIDE;
+
+ void ProcessAdditionalValues(cmCTestGenericHandler* handler) CM_OVERRIDE;
+
+ enum
+ {
+ ctm_DEFECT_COUNT = ctt_LAST,
+ ctm_LAST
+ };
};
#endif
diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx
index 0052a16..c18e20c 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()) {
@@ -702,6 +708,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckSanitizerOutput(
ostr << *i << std::endl;
}
log = ostr.str();
+ this->DefectCount += defects;
return defects == 0;
}
bool cmCTestMemCheckHandler::ProcessMemCheckPurifyOutput(
@@ -743,6 +750,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckPurifyOutput(
}
log = ostr.str();
+ this->DefectCount += defects;
return defects == 0;
}
@@ -878,6 +886,7 @@ bool cmCTestMemCheckHandler::ProcessMemCheckValgrindOutput(
<< (cmSystemTools::GetTime() - sttime) << std::endl,
this->Quiet);
log = ostr.str();
+ this->DefectCount += defects;
return defects == 0;
}
@@ -923,9 +932,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
diff --git a/Source/CTest/cmCTestMemCheckHandler.h b/Source/CTest/cmCTestMemCheckHandler.h
index b12da28..5faace0 100644
--- a/Source/CTest/cmCTestMemCheckHandler.h
+++ b/Source/CTest/cmCTestMemCheckHandler.h
@@ -30,6 +30,8 @@ public:
void Initialize() CM_OVERRIDE;
+ int GetDefectCount();
+
protected:
int PreProcessHandler() CM_OVERRIDE;
int PostProcessHandler() CM_OVERRIDE;
@@ -105,6 +107,7 @@ private:
std::vector<std::string> ResultStringsLong;
std::vector<int> GlobalResults;
bool LogWithPID; // does log file add pid
+ int DefectCount;
std::vector<int>::size_type FindOrAddWarning(const std::string& warning);
// initialize the ResultStrings and ResultStringsLong for
diff --git a/Tests/RunCMake/ctest_memcheck/DummyLeakSanitizerPrintDefects-result.txt b/Tests/RunCMake/ctest_memcheck/DummyLeakSanitizerPrintDefects-result.txt
new file mode 100644
index 0000000..b57e2de
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyLeakSanitizerPrintDefects-result.txt
@@ -0,0 +1 @@
+(-1|255)
diff --git a/Tests/RunCMake/ctest_memcheck/DummyLeakSanitizerPrintDefects-stderr.txt b/Tests/RunCMake/ctest_memcheck/DummyLeakSanitizerPrintDefects-stderr.txt
new file mode 100644
index 0000000..d4b71ae
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyLeakSanitizerPrintDefects-stderr.txt
@@ -0,0 +1 @@
+Defect count: 3
diff --git a/Tests/RunCMake/ctest_memcheck/DummyLeakSanitizerPrintDefects-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyLeakSanitizerPrintDefects-stdout.txt
new file mode 100644
index 0000000..97a8a9b
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyLeakSanitizerPrintDefects-stdout.txt
@@ -0,0 +1,3 @@
+Memory checking results:
+Direct leak - 2
+Indirect leak - 1
diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindNoDefects-result.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindNoDefects-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindNoDefects-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindNoDefects-stderr.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindNoDefects-stderr.txt
new file mode 100644
index 0000000..ad28645
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindNoDefects-stderr.txt
@@ -0,0 +1 @@
+Defect count: 0
diff --git a/Tests/RunCMake/ctest_memcheck/DummyValgrindNoDefects-stdout.txt b/Tests/RunCMake/ctest_memcheck/DummyValgrindNoDefects-stdout.txt
new file mode 100644
index 0000000..dabb004
--- /dev/null
+++ b/Tests/RunCMake/ctest_memcheck/DummyValgrindNoDefects-stdout.txt
@@ -0,0 +1,6 @@
+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:
diff --git a/Tests/RunCMake/ctest_memcheck/RunCMakeTest.cmake b/Tests/RunCMake/ctest_memcheck/RunCMakeTest.cmake
index 5ad6511..212bfdb 100644
--- a/Tests/RunCMake/ctest_memcheck/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ctest_memcheck/RunCMakeTest.cmake
@@ -12,6 +12,8 @@ endfunction()
unset(CTEST_EXTRA_CONFIG)
unset(CTEST_EXTRA_CODE)
+unset(CTEST_SUFFIX_CODE)
+unset(CTEST_MEMCHECK_ARGS)
unset(CMAKELISTS_EXTRA_CODE)
#-----------------------------------------------------------------------------
@@ -132,4 +134,31 @@ run_mc_test(DummyValgrindNoLogFile "${PSEUDO_VALGRIND_NOLOG}")
run_mc_test(DummyBCNoLogFile "${PSEUDO_BC_NOLOG}")
run_mc_test(NotExist "\${CTEST_BINARY_DIRECTORY}/no-memcheck-exe")
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)
diff --git a/Tests/RunCMake/ctest_memcheck/test.cmake.in b/Tests/RunCMake/ctest_memcheck/test.cmake.in
index 8431fa6..50b4b6a 100644
--- a/Tests/RunCMake/ctest_memcheck/test.cmake.in
+++ b/Tests/RunCMake/ctest_memcheck/test.cmake.in
@@ -21,4 +21,6 @@ set(CTEST_MEMORYCHECK_TYPE "${MEMCHECK_TYPE}")
CTEST_START(Experimental)
CTEST_CONFIGURE(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@