mirror of
https://github.com/Kitware/CMake.git
synced 2026-05-06 14:19:59 -05:00
Merge topic 'ctest_memcheck-leak_sanitizer'
e537bd91ctest_memcheck: do not add detect_leaks=1 to ASAN_OPTIONS0a2e5885ctest_memcheck: join *SAN_OPTIONS with :cdacfbd2MEMORYCHECK_SUPPRESSIONS_FILE: add support for sanitizerscf590c12ctest_memcheck: add support for standalone LeakSanitizer
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
ctest_memcheck-leak_sanitizer
|
||||
=============================
|
||||
|
||||
* The :command:`ctest_memcheck` command learned to support ``LeakSanitizer``
|
||||
independently from ``AddressSanitizer``.
|
||||
|
||||
* The :command:`ctest_memcheck` command no longer automatically adds
|
||||
``leak_check=1`` to the options used by ``AddressSanitizer``. The default
|
||||
behavior of ``AddressSanitizer`` is to run `LeakSanitizer` to check leaks
|
||||
unless ``leak_check=0``.
|
||||
|
||||
* The :command:`ctest_memcheck` command learned to read the location of
|
||||
suppressions files for sanitizers from the
|
||||
:variable:`CTEST_MEMORYCHECK_SUPPRESSIONS_FILE` variable.
|
||||
|
||||
* The :command:`ctest_memcheck` command was fixed to correctly append extra
|
||||
sanitizer options read from the
|
||||
:variable:`CTEST_MEMORYCHECK_SANITIZER_OPTIONS` variable to the environment
|
||||
variables used internally by the sanitizers.
|
||||
@@ -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``.
|
||||
|
||||
@@ -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: {
|
||||
@@ -597,12 +607,20 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
|
||||
this->MemoryTesterDynamicOptions.push_back("-E");
|
||||
this->MemoryTesterDynamicOptions.push_back("env");
|
||||
std::string envVar;
|
||||
std::string extraOptions =
|
||||
std::string extraOptions = ":" +
|
||||
this->CTest->GetCTestConfiguration("MemoryCheckSanitizerOptions");
|
||||
std::string suppressionsOption;
|
||||
if (!this->CTest->GetCTestConfiguration("MemoryCheckSuppressionFile")
|
||||
.empty()) {
|
||||
suppressionsOption = ":suppressions=" +
|
||||
this->CTest->GetCTestConfiguration("MemoryCheckSuppressionFile");
|
||||
}
|
||||
if (this->MemoryTesterStyle ==
|
||||
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";
|
||||
@@ -614,8 +632,9 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking()
|
||||
envVar = "UBSAN_OPTIONS";
|
||||
}
|
||||
std::string outputFile =
|
||||
envVar + "=log_path=\"" + this->MemoryTesterOutputFile + "\" ";
|
||||
this->MemoryTesterEnvironmentVariable = outputFile + extraOptions;
|
||||
envVar + "=log_path=\"" + this->MemoryTesterOutputFile + "\"";
|
||||
this->MemoryTesterEnvironmentVariable =
|
||||
outputFile + extraOptions + suppressionsOption;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -644,6 +663,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 +700,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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
(-1|255)
|
||||
@@ -0,0 +1 @@
|
||||
Cannot find memory tester output file: .*/Tests/RunCMake/ctest_memcheck/DummyAddressLeakSanitizer-build/Testing/Temporary/MemoryChecker.1.log\.\*
|
||||
@@ -0,0 +1,3 @@
|
||||
Memory checking results:
|
||||
Direct leak - 2
|
||||
Indirect leak - 1
|
||||
@@ -30,22 +30,22 @@ 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\")
|
||||
"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(DummyLeakSanitizer "" -DMEMCHECK_TYPE=AddressSanitizer)
|
||||
run_mc_test(DummyLeakSanitizer "" -DMEMCHECK_TYPE=LeakSanitizer)
|
||||
unset(CMAKELISTS_EXTRA_CODE)
|
||||
unset(CTEST_EXTRA_CODE)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# add AddressSanitizer test
|
||||
set(CTEST_EXTRA_CODE
|
||||
"set(CTEST_MEMORYCHECK_SANITIZER_OPTIONS \"simulate_sanitizer=1 report_bugs=1 history_size=5 exitcode=55\")
|
||||
"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}\"
|
||||
@@ -55,10 +55,23 @@ 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
|
||||
"set(CTEST_MEMORYCHECK_COMMAND_OPTIONS \"simulate_sanitizer=1 report_bugs=1 history_size=5 exitcode=55\")
|
||||
"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}\"
|
||||
@@ -151,13 +164,13 @@ 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(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)
|
||||
run_mc_test(DummyLeakSanitizerPrintDefects "" -DMEMCHECK_TYPE=LeakSanitizer)
|
||||
unset(CMAKELISTS_EXTRA_CODE)
|
||||
unset(CTEST_EXTRA_CODE)
|
||||
unset(CTEST_MEMCHECK_ARGS)
|
||||
|
||||
@@ -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).
|
||||
")
|
||||
@@ -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).
|
||||
")
|
||||
|
||||
Reference in New Issue
Block a user