summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2014-10-08 14:48:12 (GMT)
committerCMake Topic Stage <kwrobot@kitware.com>2014-10-08 14:48:12 (GMT)
commitec941fc04bf4facc7ffe45142351126262fdddee (patch)
tree19e4bdf95913c38eb735b4cbdcd17b49fa9d6d03
parent26a8b64f7d98c02e0f489e9e1e12e3484ded8bec (diff)
parente0e75a7201d4189693b409f14a3280b6b94a5f51 (diff)
downloadCMake-ec941fc04bf4facc7ffe45142351126262fdddee.zip
CMake-ec941fc04bf4facc7ffe45142351126262fdddee.tar.gz
CMake-ec941fc04bf4facc7ffe45142351126262fdddee.tar.bz2
Merge topic 'ctest-memcheck-sanitizers'
e0e75a72 Help: Add notes for topic 'ctest-memcheck-sanitizers' 7345a1f7 tests: Add a test for ctest_memcheck MemorySanitizer 0c6330da ctest_memcheck: Add support for MemorySanitizer msan 9ba8bf12 tests: add a test for ctest_memcheck UndefinedBehaviorSanitizer 816c100a ctest_memcheck: Add support for UndefinedBehaviorSanitizer ubsan b67ef537 ctest_memcheck: Order sanitizer type code consistently f48a2968 Tests: Organize CTestTestMemcheck inner test code
-rw-r--r--Help/release/dev/ctest-memcheck-sanitizers.rst8
-rw-r--r--Help/release/dev/thread-sanitizer.rst5
-rw-r--r--Help/variable/CTEST_MEMORYCHECK_TYPE.rst2
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.cxx79
-rw-r--r--Source/CTest/cmCTestMemCheckHandler.h4
-rw-r--r--Tests/CTestTestMemcheck/CMakeLists.txt42
-rw-r--r--Tests/CTestTestMemcheck/testMemorySanitizer.cmake27
-rw-r--r--Tests/CTestTestMemcheck/testUndefinedBehaviorSanitizer.cmake21
8 files changed, 161 insertions, 27 deletions
diff --git a/Help/release/dev/ctest-memcheck-sanitizers.rst b/Help/release/dev/ctest-memcheck-sanitizers.rst
new file mode 100644
index 0000000..fa8fb81
--- /dev/null
+++ b/Help/release/dev/ctest-memcheck-sanitizers.rst
@@ -0,0 +1,8 @@
+ctest-memcheck-sanitizers
+-------------------------
+
+* The :command:`ctest_memcheck` command learned to support sanitizer
+ modes, including ``AddressSanitizer``, ``MemorySanitizer``,
+ ``ThreadSanitizer``, and ``UndefinedBehaviorSanitizer``.
+ Options may be set using the new
+ :variable:`CTEST_MEMORYCHECK_SANITIZER_OPTIONS` variable.
diff --git a/Help/release/dev/thread-sanitizer.rst b/Help/release/dev/thread-sanitizer.rst
deleted file mode 100644
index f38e8e1..0000000
--- a/Help/release/dev/thread-sanitizer.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-thread-sanitizer
-----------------
-
-* The :command:`ctest_memcheck` command learned to support
- ``ThreadSanitizer``.
diff --git a/Help/variable/CTEST_MEMORYCHECK_TYPE.rst b/Help/variable/CTEST_MEMORYCHECK_TYPE.rst
index e8d5461..f1087c0 100644
--- a/Help/variable/CTEST_MEMORYCHECK_TYPE.rst
+++ b/Help/variable/CTEST_MEMORYCHECK_TYPE.rst
@@ -4,4 +4,4 @@ CTEST_MEMORYCHECK_TYPE
Specify the CTest ``MemoryCheckType`` setting
in a :manual:`ctest(1)` dashboard client script.
Valid values are Valgrind, Purify, BoundsChecker, and ThreadSanitizer,
-and AddressSanitizer.
+AddressSanitizer, MemorySanitizer, and UndefinedBehaviorSanitizer.
diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx
index 16ac37c..4835010 100644
--- a/Source/CTest/cmCTestMemCheckHandler.cxx
+++ b/Source/CTest/cmCTestMemCheckHandler.cxx
@@ -370,11 +370,17 @@ void cmCTestMemCheckHandler::GenerateDartOutput(std::ostream& os)
case cmCTestMemCheckHandler::BOUNDS_CHECKER:
os << "BoundsChecker";
break;
+ case cmCTestMemCheckHandler::ADDRESS_SANITIZER:
+ os << "AddressSanitizer";
+ break;
case cmCTestMemCheckHandler::THREAD_SANITIZER:
os << "ThreadSanitizer";
break;
- case cmCTestMemCheckHandler::ADDRESS_SANITIZER:
- os << "AddressSanitizer";
+ case cmCTestMemCheckHandler::MEMORY_SANITIZER:
+ os << "MemorySanitizer";
+ break;
+ case cmCTestMemCheckHandler::UB_SANITIZER:
+ os << "UndefinedBehaviorSanitizer";
break;
default:
os << "Unknown";
@@ -537,6 +543,14 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
this->MemoryTesterStyle = cmCTestMemCheckHandler::BOUNDS_CHECKER;
}
if ( this->CTest->GetCTestConfiguration("MemoryCheckType")
+ == "AddressSanitizer")
+ {
+ this->MemoryTester
+ = this->CTest->GetCTestConfiguration("CMakeCommand").c_str();
+ this->MemoryTesterStyle = cmCTestMemCheckHandler::ADDRESS_SANITIZER;
+ this->LogWithPID = true; // even if we give the log file the pid is added
+ }
+ if ( this->CTest->GetCTestConfiguration("MemoryCheckType")
== "ThreadSanitizer")
{
this->MemoryTester
@@ -545,11 +559,19 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
this->LogWithPID = true; // even if we give the log file the pid is added
}
if ( this->CTest->GetCTestConfiguration("MemoryCheckType")
- == "AddressSanitizer")
+ == "MemorySanitizer")
{
this->MemoryTester
= this->CTest->GetCTestConfiguration("CMakeCommand").c_str();
- this->MemoryTesterStyle = cmCTestMemCheckHandler::ADDRESS_SANITIZER;
+ this->MemoryTesterStyle = cmCTestMemCheckHandler::MEMORY_SANITIZER;
+ this->LogWithPID = true; // even if we give the log file the pid is added
+ }
+ if ( this->CTest->GetCTestConfiguration("MemoryCheckType")
+ == "UndefinedBehaviorSanitizer")
+ {
+ this->MemoryTester
+ = this->CTest->GetCTestConfiguration("CMakeCommand").c_str();
+ this->MemoryTesterStyle = cmCTestMemCheckHandler::UB_SANITIZER;
this->LogWithPID = true; // even if we give the log file the pid is added
}
// Check the MemoryCheckType
@@ -674,10 +696,11 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
this->MemoryTesterOptions.push_back("/M");
break;
}
- // these two are almost the same but the env var used
- // is different
+ // these are almost the same but the env var used is different
case cmCTestMemCheckHandler::ADDRESS_SANITIZER:
case cmCTestMemCheckHandler::THREAD_SANITIZER:
+ case cmCTestMemCheckHandler::MEMORY_SANITIZER:
+ case cmCTestMemCheckHandler::UB_SANITIZER:
{
// To pass arguments to ThreadSanitizer the environment variable
// TSAN_OPTIONS is used. This is done with the cmake -E env command.
@@ -689,15 +712,24 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
std::string envVar;
std::string extraOptions =
this->CTest->GetCTestConfiguration("MemoryCheckSanitizerOptions");
- if(this->MemoryTesterStyle == cmCTestMemCheckHandler::THREAD_SANITIZER)
+ if(this->MemoryTesterStyle == cmCTestMemCheckHandler::ADDRESS_SANITIZER)
+ {
+ envVar = "ASAN_OPTIONS";
+ extraOptions += " detect_leaks=1";
+ }
+ else if(this->MemoryTesterStyle ==
+ cmCTestMemCheckHandler::THREAD_SANITIZER)
{
envVar = "TSAN_OPTIONS";
}
else if(this->MemoryTesterStyle ==
- cmCTestMemCheckHandler::ADDRESS_SANITIZER)
+ cmCTestMemCheckHandler::MEMORY_SANITIZER)
{
- envVar = "ASAN_OPTIONS";
- extraOptions += " detect_leaks=1";
+ envVar = "MSAN_OPTIONS";
+ }
+ else if(this->MemoryTesterStyle == cmCTestMemCheckHandler::UB_SANITIZER)
+ {
+ envVar = "UBSAN_OPTIONS";
}
std::string outputFile = envVar + "=log_path=\""
+ this->MemoryTesterOutputFile + "\" ";
@@ -734,9 +766,13 @@ ProcessMemCheckOutput(const std::string& str,
return this->ProcessMemCheckPurifyOutput(str, log, results);
}
else if ( this->MemoryTesterStyle ==
+ cmCTestMemCheckHandler::ADDRESS_SANITIZER ||
+ this->MemoryTesterStyle ==
cmCTestMemCheckHandler::THREAD_SANITIZER ||
this->MemoryTesterStyle ==
- cmCTestMemCheckHandler::ADDRESS_SANITIZER)
+ cmCTestMemCheckHandler::MEMORY_SANITIZER ||
+ this->MemoryTesterStyle ==
+ cmCTestMemCheckHandler::UB_SANITIZER)
{
return this->ProcessMemCheckSanitizerOutput(str, log, results);
}
@@ -776,13 +812,22 @@ bool cmCTestMemCheckHandler::ProcessMemCheckSanitizerOutput(
std::vector<int>& result)
{
std::string regex;
- if(this->MemoryTesterStyle == cmCTestMemCheckHandler::THREAD_SANITIZER)
- {
- regex = "WARNING: ThreadSanitizer: (.*) \\(pid=.*\\)";
- }
- else
+ switch ( this->MemoryTesterStyle )
{
- regex = "ERROR: AddressSanitizer: (.*) on.*";
+ case cmCTestMemCheckHandler::ADDRESS_SANITIZER:
+ regex = "ERROR: AddressSanitizer: (.*) on.*";
+ break;
+ case cmCTestMemCheckHandler::THREAD_SANITIZER:
+ regex = "WARNING: ThreadSanitizer: (.*) \\(pid=.*\\)";
+ break;
+ case cmCTestMemCheckHandler::MEMORY_SANITIZER:
+ regex = "WARNING: MemorySanitizer: (.*)";
+ break;
+ case cmCTestMemCheckHandler::UB_SANITIZER:
+ regex = "runtime error: (.*)";
+ break;
+ default:
+ break;
}
cmsys::RegularExpression sanitizerWarning(regex);
cmsys::RegularExpression leakWarning("(Direct|Indirect) leak of .*");
diff --git a/Source/CTest/cmCTestMemCheckHandler.h b/Source/CTest/cmCTestMemCheckHandler.h
index f442376..69fdd9f 100644
--- a/Source/CTest/cmCTestMemCheckHandler.h
+++ b/Source/CTest/cmCTestMemCheckHandler.h
@@ -50,8 +50,10 @@ private:
PURIFY,
BOUNDS_CHECKER,
// checkers after here do not use the standard error list
+ ADDRESS_SANITIZER,
THREAD_SANITIZER,
- ADDRESS_SANITIZER
+ MEMORY_SANITIZER,
+ UB_SANITIZER
};
public:
enum { // Memory faults
diff --git a/Tests/CTestTestMemcheck/CMakeLists.txt b/Tests/CTestTestMemcheck/CMakeLists.txt
index 7422eb5..2023e74 100644
--- a/Tests/CTestTestMemcheck/CMakeLists.txt
+++ b/Tests/CTestTestMemcheck/CMakeLists.txt
@@ -103,11 +103,11 @@ unset(CTEST_EXTRA_CONFIG)
unset(CTEST_EXTRA_CODE)
unset(CMAKELISTS_EXTRA_CODE)
+#-----------------------------------------------------------------------------
# add ThreadSanitizer test
set(CTEST_EXTRA_CODE
"set(CTEST_MEMORYCHECK_COMMAND_OPTIONS \"report_bugs=1 history_size=5 exitcode=55\")
")
-
set(CMAKELISTS_EXTRA_CODE
"add_test(NAME TestSan COMMAND \"${CMAKE_COMMAND}\"
-P \"${CMAKE_CURRENT_SOURCE_DIR}/testThreadSanitizer.cmake\")
@@ -119,11 +119,11 @@ set_tests_properties(CTestTestMemcheckDummyThreadSanitizer PROPERTIES
set(CMAKELISTS_EXTRA_CODE )
set(CTEST_EXTRA_CODE)
+#-----------------------------------------------------------------------------
# add LeakSanitizer test
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 \"${CMAKE_CURRENT_SOURCE_DIR}/testLeakSanitizer.cmake\")
@@ -134,11 +134,12 @@ set(CTEST_EXTRA_CODE)
set_tests_properties(CTestTestMemcheckDummyLeakSanitizer PROPERTIES
PASS_REGULAR_EXPRESSION
".*Memory checking results:.*Direct leak - 2.*Indirect leak - 1.*")
+
+#-----------------------------------------------------------------------------
# add AddressSanitizer test
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 \"${CMAKE_CURRENT_SOURCE_DIR}/testAddressSanitizer.cmake\")
@@ -150,6 +151,41 @@ set_tests_properties(CTestTestMemcheckDummyAddressSanitizer PROPERTIES
PASS_REGULAR_EXPRESSION
".*Memory checking results:.*heap-buffer-overflow - 1.*")
+#-----------------------------------------------------------------------------
+# add MemorySanitizer test
+set(CTEST_EXTRA_CODE
+"set(CTEST_MEMORYCHECK_COMMAND_OPTIONS \"simulate_sanitizer=1 report_bugs=1 history_size=5 exitcode=55\")
+")
+
+set(CMAKELISTS_EXTRA_CODE
+"add_test(NAME TestSan COMMAND \"${CMAKE_COMMAND}\"
+-P \"${CMAKE_CURRENT_SOURCE_DIR}/testMemorySanitizer.cmake\")
+")
+gen_mc_test_internal(DummyMemorySanitizer "" -DMEMCHECK_TYPE=MemorySanitizer)
+set(CMAKELISTS_EXTRA_CODE )
+set(CTEST_EXTRA_CODE)
+set_tests_properties(CTestTestMemcheckDummyMemorySanitizer PROPERTIES
+ PASS_REGULAR_EXPRESSION
+ ".*Memory checking results:.*use-of-uninitialized-value - 1.*")
+
+#-----------------------------------------------------------------------------
+# add UndefinedBehaviorSanitizer test
+set(CTEST_EXTRA_CODE
+"set(CTEST_MEMORYCHECK_SANITIZER_OPTIONS \"simulate_sanitizer=1\")
+")
+
+set(CMAKELISTS_EXTRA_CODE
+"add_test(NAME TestSan COMMAND \"${CMAKE_COMMAND}\"
+-P \"${CMAKE_CURRENT_SOURCE_DIR}/testUndefinedBehaviorSanitizer.cmake\")
+")
+gen_mc_test_internal(DummyUndefinedBehaviorSanitizer "" -DMEMCHECK_TYPE=UndefinedBehaviorSanitizer)
+set(CMAKELISTS_EXTRA_CODE )
+set(CTEST_EXTRA_CODE)
+set_tests_properties(CTestTestMemcheckDummyUndefinedBehaviorSanitizer PROPERTIES
+ PASS_REGULAR_EXPRESSION
+ ".*Memory checking results:.*left shift of negative value -256 - 1.*")
+
+#-----------------------------------------------------------------------------
gen_mc_test(DummyPurify "\${PSEUDO_PURIFY}")
gen_mc_test(DummyValgrind "\${PSEUDO_VALGRIND}")
diff --git a/Tests/CTestTestMemcheck/testMemorySanitizer.cmake b/Tests/CTestTestMemcheck/testMemorySanitizer.cmake
new file mode 100644
index 0000000..c87af9a
--- /dev/null
+++ b/Tests/CTestTestMemcheck/testMemorySanitizer.cmake
@@ -0,0 +1,27 @@
+# this file simulates a program that has been built with thread sanitizer
+# options
+
+message("MSAN_OPTIONS = [$ENV{MSAN_OPTIONS}]")
+string(REGEX REPLACE ".*log_path=\"([^\"]*)\".*" "\\1" LOG_FILE "$ENV{MSAN_OPTIONS}")
+message("LOG_FILE=[${LOG_FILE}]")
+
+# if we are not asked to simulate address sanitizer don't do it
+if(NOT "$ENV{MSAN_OPTIONS}]" MATCHES "simulate_sanitizer.1")
+ return()
+endif()
+# clear the log file
+file(REMOVE "${LOG_FILE}.2343")
+
+# create an error of each type of thread santizer
+# these names come from tsan_report.cc in llvm
+
+file(APPEND "${LOG_FILE}.2343"
+"=================================================================
+==28423== WARNING: MemorySanitizer: use-of-uninitialized-value
+ #0 0x7f4364210dd9 in main (/home/kitware/msan/msan-bin/umr+0x7bdd9)
+ #1 0x7f4362d9376c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226
+ #2 0x7f4364210b0c in _start (/home/kitware/msan/msan-bin/umr+0x7bb0c)
+
+SUMMARY: MemorySanitizer: use-of-uninitialized-value ??:0 main
+Exiting
+")
diff --git a/Tests/CTestTestMemcheck/testUndefinedBehaviorSanitizer.cmake b/Tests/CTestTestMemcheck/testUndefinedBehaviorSanitizer.cmake
new file mode 100644
index 0000000..8ef3c0a
--- /dev/null
+++ b/Tests/CTestTestMemcheck/testUndefinedBehaviorSanitizer.cmake
@@ -0,0 +1,21 @@
+# this file simulates a program that has been built with undefined behavior
+# sanitizer options
+
+message("UBSAN_OPTIONS = [$ENV{UBSAN_OPTIONS}]")
+string(REGEX REPLACE ".*log_path=\"([^\"]*)\".*" "\\1" LOG_FILE "$ENV{UBSAN_OPTIONS}")
+message("LOG_FILE=[${LOG_FILE}]")
+
+# if we are not asked to simulate address sanitizer don't do it
+if(NOT "$ENV{UBSAN_OPTIONS}]" MATCHES "simulate_sanitizer.1")
+ return()
+endif()
+# clear the log file
+file(REMOVE "${LOG_FILE}.2343")
+
+# create an error like undefined behavior santizer creates;
+# these names come from ubsan_diag.cc and ubsan_handlers.cc
+# in llvm
+
+file(APPEND "${LOG_FILE}.2343"
+"<unknown>: runtime error: left shift of negative value -256
+")