Add a basic TSan test for ref-counts.
Confirmed that, if the locks are commented out, TSan catches the threading error. Change-Id: I3e4ef9a7ca85fdbacf8c8b13694a5a54c6d5f99b Reviewed-on: https://boringssl-review.googlesource.com/29924 Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
parent
20b6a4e2a1
commit
5852cfccbc
@ -268,6 +268,16 @@ if(CFI)
|
|||||||
set(OPENSSL_NO_ASM "1")
|
set(OPENSSL_NO_ASM "1")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(TSAN)
|
||||||
|
if(NOT CLANG)
|
||||||
|
message(FATAL_ERROR "Cannot enable TSAN unless using Clang")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=thread")
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread")
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=thread")
|
||||||
|
endif()
|
||||||
|
|
||||||
if (GCOV)
|
if (GCOV)
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
|
||||||
|
@ -16,6 +16,10 @@
|
|||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#if !defined(OPENSSL_NO_THREADS)
|
||||||
|
#include <thread>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
TEST(RefCountTest, Basic) {
|
TEST(RefCountTest, Basic) {
|
||||||
CRYPTO_refcount_t count = 0;
|
CRYPTO_refcount_t count = 0;
|
||||||
@ -38,3 +42,38 @@ TEST(RefCountTest, Basic) {
|
|||||||
EXPECT_FALSE(CRYPTO_refcount_dec_and_test_zero(&count));
|
EXPECT_FALSE(CRYPTO_refcount_dec_and_test_zero(&count));
|
||||||
EXPECT_EQ(1u, count);
|
EXPECT_EQ(1u, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(OPENSSL_NO_THREADS)
|
||||||
|
// This test is primarily intended to run under ThreadSanitizer.
|
||||||
|
TEST(RefCountTest, Threads) {
|
||||||
|
CRYPTO_refcount_t count = 0;
|
||||||
|
|
||||||
|
// Race two increments.
|
||||||
|
{
|
||||||
|
std::thread thread([&] { CRYPTO_refcount_inc(&count); });
|
||||||
|
CRYPTO_refcount_inc(&count);
|
||||||
|
thread.join();
|
||||||
|
EXPECT_EQ(2u, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Race an increment with a decrement.
|
||||||
|
{
|
||||||
|
std::thread thread([&] { CRYPTO_refcount_inc(&count); });
|
||||||
|
EXPECT_FALSE(CRYPTO_refcount_dec_and_test_zero(&count));
|
||||||
|
thread.join();
|
||||||
|
EXPECT_EQ(2u, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Race two decrements.
|
||||||
|
{
|
||||||
|
bool thread_saw_zero;
|
||||||
|
std::thread thread(
|
||||||
|
[&] { thread_saw_zero = CRYPTO_refcount_dec_and_test_zero(&count); });
|
||||||
|
bool saw_zero = CRYPTO_refcount_dec_and_test_zero(&count);
|
||||||
|
thread.join();
|
||||||
|
EXPECT_EQ(0u, count);
|
||||||
|
// Exactly one thread should see zero.
|
||||||
|
EXPECT_NE(saw_zero, thread_saw_zero);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user