From 816c100ae2d1ef9ad42186a260724a279b6b5934 Mon Sep 17 00:00:00 2001 From: Ben Boeckel Date: Fri, 3 Oct 2014 13:46:18 -0400 Subject: [PATCH] ctest_memcheck: Add support for UndefinedBehaviorSanitizer ubsan UBSan instruments a build and logs messages on any undefined behavior instances. --- Help/variable/CTEST_MEMORYCHECK_TYPE.rst | 2 +- Source/CTest/cmCTestMemCheckHandler.cxx | 23 ++++++++++++++++++++++- Source/CTest/cmCTestMemCheckHandler.h | 3 ++- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/Help/variable/CTEST_MEMORYCHECK_TYPE.rst b/Help/variable/CTEST_MEMORYCHECK_TYPE.rst index e8d5461ac..af759e9dc 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, and UndefinedBehaviorSanitizer. diff --git a/Source/CTest/cmCTestMemCheckHandler.cxx b/Source/CTest/cmCTestMemCheckHandler.cxx index 8a8a3734e..cc691aa73 100644 --- a/Source/CTest/cmCTestMemCheckHandler.cxx +++ b/Source/CTest/cmCTestMemCheckHandler.cxx @@ -376,6 +376,9 @@ void cmCTestMemCheckHandler::GenerateDartOutput(std::ostream& os) case cmCTestMemCheckHandler::THREAD_SANITIZER: os << "ThreadSanitizer"; break; + case cmCTestMemCheckHandler::UB_SANITIZER: + os << "UndefinedBehaviorSanitizer"; + break; default: os << "Unknown"; } @@ -552,6 +555,14 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking() this->MemoryTesterStyle = cmCTestMemCheckHandler::THREAD_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 if(this->MemoryTesterStyle == cmCTestMemCheckHandler::UNKNOWN) { @@ -677,6 +688,7 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking() // these are almost the same but the env var used is different case cmCTestMemCheckHandler::ADDRESS_SANITIZER: case cmCTestMemCheckHandler::THREAD_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. @@ -698,6 +710,10 @@ bool cmCTestMemCheckHandler::InitializeMemoryChecking() { envVar = "TSAN_OPTIONS"; } + else if(this->MemoryTesterStyle == cmCTestMemCheckHandler::UB_SANITIZER) + { + envVar = "UBSAN_OPTIONS"; + } std::string outputFile = envVar + "=log_path=\"" + this->MemoryTesterOutputFile + "\" "; this->MemoryTesterEnvironmentVariable = outputFile + extraOptions; @@ -735,7 +751,9 @@ ProcessMemCheckOutput(const std::string& str, else if ( this->MemoryTesterStyle == cmCTestMemCheckHandler::ADDRESS_SANITIZER || this->MemoryTesterStyle == - cmCTestMemCheckHandler::THREAD_SANITIZER) + cmCTestMemCheckHandler::THREAD_SANITIZER || + this->MemoryTesterStyle == + cmCTestMemCheckHandler::UB_SANITIZER) { return this->ProcessMemCheckSanitizerOutput(str, log, results); } @@ -783,6 +801,9 @@ bool cmCTestMemCheckHandler::ProcessMemCheckSanitizerOutput( case cmCTestMemCheckHandler::THREAD_SANITIZER: regex = "WARNING: ThreadSanitizer: (.*) \\(pid=.*\\)"; break; + case cmCTestMemCheckHandler::UB_SANITIZER: + regex = "runtime error: (.*)"; + break; default: break; } diff --git a/Source/CTest/cmCTestMemCheckHandler.h b/Source/CTest/cmCTestMemCheckHandler.h index 3ceaa25f8..f5cc91cb5 100644 --- a/Source/CTest/cmCTestMemCheckHandler.h +++ b/Source/CTest/cmCTestMemCheckHandler.h @@ -51,7 +51,8 @@ private: BOUNDS_CHECKER, // checkers after here do not use the standard error list ADDRESS_SANITIZER, - THREAD_SANITIZER + THREAD_SANITIZER, + UB_SANITIZER }; public: enum { // Memory faults