ctest_memcheck: add support for standalone LeakSanitizer

This commit is contained in:
Jamie Snape 2017-01-09 13:15:42 -05:00
parent 976574b010
commit cf590c1236
10 changed files with 102 additions and 14 deletions

View File

@ -0,0 +1,5 @@
ctest_memcheck-leak_sanitizer
=============================
* The :command:`ctest_memcheck` command learned to support ``LeakSanitizer``
independently from ``AddressSanitizer``.

View File

@ -4,5 +4,5 @@ CTEST_MEMORYCHECK_TYPE
Specify the CTest ``MemoryCheckType`` setting
in a :manual:`ctest(1)` dashboard client script.
Valid values are ``Valgrind``, ``Purify``, ``BoundsChecker``, and
``ThreadSanitizer``, ``AddressSanitizer``, ``MemorySanitizer``, and
``ThreadSanitizer``, ``AddressSanitizer``, ``LeakSanitizer``, ``MemorySanitizer``, and
``UndefinedBehaviorSanitizer``.

View File

@ -305,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;
@ -458,6 +461,12 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
this->MemoryTesterStyle = cmCTestMemCheckHandler::ADDRESS_SANITIZER;
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");
@ -586,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: {
@ -603,6 +613,9 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
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";
@ -644,6 +657,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:
@ -680,6 +694,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;

View File

@ -47,6 +47,7 @@ private:
BOUNDS_CHECKER,
// checkers after here do not use the standard error list
ADDRESS_SANITIZER,
LEAK_SANITIZER,
THREAD_SANITIZER,
MEMORY_SANITIZER,
UB_SANITIZER

View File

@ -0,0 +1 @@
(-1|255)

View File

@ -0,0 +1 @@
Cannot find memory tester output file: .*/Tests/RunCMake/ctest_memcheck/DummyAddressLeakSanitizer-build/Testing/Temporary/MemoryChecker.1.log\.\*

View File

@ -0,0 +1,3 @@
Memory checking results:
Direct leak - 2
Indirect leak - 1

View File

@ -30,7 +30,7 @@ unset(CMAKELISTS_EXTRA_CODE)
unset(CTEST_EXTRA_CODE)
#-----------------------------------------------------------------------------
# add LeakSanitizer test
# add standalone LeakSanitizer test
set(CTEST_EXTRA_CODE
"set(CTEST_MEMORYCHECK_SANITIZER_OPTIONS \"simulate_sanitizer=1 report_bugs=1 history_size=5 exitcode=55\")
")
@ -38,7 +38,7 @@ set(CMAKELISTS_EXTRA_CODE
"add_test(NAME TestSan COMMAND \"${CMAKE_COMMAND}\"
-P \"${RunCMake_SOURCE_DIR}/testLeakSanitizer.cmake\")
")
run_mc_test(DummyLeakSanitizer "" -DMEMCHECK_TYPE=AddressSanitizer)
run_mc_test(DummyLeakSanitizer "" -DMEMCHECK_TYPE=LeakSanitizer)
unset(CMAKELISTS_EXTRA_CODE)
unset(CTEST_EXTRA_CODE)
@ -55,6 +55,19 @@ run_mc_test(DummyAddressSanitizer "" -DMEMCHECK_TYPE=AddressSanitizer)
unset(CMAKELISTS_EXTRA_CODE)
unset(CTEST_EXTRA_CODE)
#-----------------------------------------------------------------------------
# add AddressSanitizer/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 \"${RunCMake_SOURCE_DIR}/testAddressLeakSanitizer.cmake\")
")
run_mc_test(DummyAddressLeakSanitizer "" -DMEMCHECK_TYPE=AddressSanitizer)
unset(CMAKELISTS_EXTRA_CODE)
unset(CTEST_EXTRA_CODE)
#-----------------------------------------------------------------------------
# add MemorySanitizer test
set(CTEST_EXTRA_CODE
@ -157,7 +170,7 @@ set(CMAKELISTS_EXTRA_CODE
"add_test(NAME TestSan COMMAND \"${CMAKE_COMMAND}\"
-P \"${RunCMake_SOURCE_DIR}/testLeakSanitizer.cmake\")
")
run_mc_test(DummyLeakSanitizerPrintDefects "" -DMEMCHECK_TYPE=AddressSanitizer)
run_mc_test(DummyLeakSanitizerPrintDefects "" -DMEMCHECK_TYPE=LeakSanitizer)
unset(CMAKELISTS_EXTRA_CODE)
unset(CTEST_EXTRA_CODE)
unset(CTEST_MEMCHECK_ARGS)

View File

@ -0,0 +1,47 @@
# this file simulates a program that has been built with AddressSanitizer
# options
message("ASAN_OPTIONS = [$ENV{ASAN_OPTIONS}]")
string(REGEX REPLACE ".*log_path=\"([^\"]*)\".*" "\\1" LOG_FILE "$ENV{ASAN_OPTIONS}")
message("LOG_FILE=[${LOG_FILE}]")
# if we are not asked to simulate AddressSanitizer don't do it
if(NOT "$ENV{ASAN_OPTIONS}]" MATCHES "simulate_sanitizer.1")
return()
endif()
# clear the log files
file(REMOVE "${LOG_FILE}.2343")
file(REMOVE "${LOG_FILE}.2344")
# create an error of each type of LeakSanitizer
file(APPEND "${LOG_FILE}.2343"
"=================================================================
==25308==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 4360 byte(s) in 1 object(s) allocated from:
#0 0x46c669 in operator new[](unsigned long) (/home/kitware/msan/a.out+0x46c669)
#1 0x4823b4 in main /home/kitware/msan/memcheck.cxx:12
#2 0x7fa72bee476c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226
SUMMARY: AddressSanitizer: 4436 byte(s) leaked in 2 allocation(s).
")
file(APPEND "${LOG_FILE}.2342"
"=================================================================
==25308==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 76 byte(s) in 1 object(s) allocated from:
#0 0x46c669 in operator new[](unsigned long) (/home/kitware/msan/a.out+0x46c669)
#1 0x4821b8 in foo() /home/kitware/msan/memcheck.cxx:4
#2 0x4823f2 in main /home/kitware/msan/memcheck.cxx:14
#3 0x7fa72bee476c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226
Indirect leak of 76 byte(s) in 1 object(s) allocated from:
#0 0x46c669 in operator new[](unsigned long) (/home/kitware/msan/a.out+0x46c669)
#1 0x4821b8 in foo() /home/kitware/msan/memcheck.cxx:4
#2 0x4823f2 in main /home/kitware/msan/memcheck.cxx:14
#3 0x7fa72bee476c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226
SUMMARY: AddressSanitizer: 4436 byte(s) leaked in 2 allocation(s).
")

View File

@ -1,20 +1,20 @@
# this file simulates a program that has been built with thread sanitizer
# this file simulates a program that has been built with LeakSanitizer
# options
message("ASAN_OPTIONS = [$ENV{ASAN_OPTIONS}]")
string(REGEX REPLACE ".*log_path=\"([^\"]*)\".*" "\\1" LOG_FILE "$ENV{ASAN_OPTIONS}")
message("LSAN_OPTIONS = [$ENV{LSAN_OPTIONS}]")
string(REGEX REPLACE ".*log_path=\"([^\"]*)\".*" "\\1" LOG_FILE "$ENV{LSAN_OPTIONS}")
message("LOG_FILE=[${LOG_FILE}]")
# if we are not asked to simulate leak sanitizer don't do it
if(NOT "$ENV{ASAN_OPTIONS}]" MATCHES "simulate_sanitizer.1")
# if we are not asked to simulate LeakSanitizer don't do it
if(NOT "$ENV{LSAN_OPTIONS}]" MATCHES "simulate_sanitizer.1")
return()
endif()
# clear the log file
# clear the log files
file(REMOVE "${LOG_FILE}.2343")
file(REMOVE "${LOG_FILE}.2344")
# create an error of each type of thread santizer
# these names come from tsan_report.cc in llvm
# create an error of each type of LeakSanitizer
file(APPEND "${LOG_FILE}.2343"
"=================================================================
@ -25,7 +25,7 @@ Direct leak of 4360 byte(s) in 1 object(s) allocated from:
#1 0x4823b4 in main /home/kitware/msan/memcheck.cxx:12
#2 0x7fa72bee476c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226
SUMMARY: AddressSanitizer: 4436 byte(s) leaked in 2 allocation(s).
SUMMARY: LeakSanitizer: 4436 byte(s) leaked in 2 allocation(s).
")
file(APPEND "${LOG_FILE}.2342"
"=================================================================
@ -43,5 +43,5 @@ Indirect leak of 76 byte(s) in 1 object(s) allocated from:
#2 0x4823f2 in main /home/kitware/msan/memcheck.cxx:14
#3 0x7fa72bee476c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226
SUMMARY: AddressSanitizer: 4436 byte(s) leaked in 2 allocation(s).
SUMMARY: LeakSanitizer: 4436 byte(s) leaked in 2 allocation(s).
")