CC=clang CXX=clang++ \
cmake \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_CXX_STANDARD=11 \
-DWITH_GLOG=ON \
-DWITH_THRIFT=OFF \
-DBUILD_UNIT_TESTS=OFF \
-DDOWNLOAD_GTEST=OFF \
-DGFLAGS_LIBRARY=/opt/gflagsRelease/lib/libgflags.so -DGFLAGS_INCLUDE_PATH=/opt/gflagsRelease/include \
-DLEVELDB_LIB=/opt/leveldbRelease/lib64/libleveldb.so -DLEVELDB_INCLUDE_PATH=/opt/leveldbRelease/include \
-DProtobuf_LIBRARY=/opt/protobuf3Release/lib/libprotobuf.so -DProtobuf_INCLUDE_DIR=/opt/protobuf3Release/include \
-DPROTOC_LIB=/opt/protobuf3Release/lib/libprotoc.so \
-DGLOG_INCLUDE_PATH=/opt/glogRelease/include -DGLOG_LIB=/opt/glogRelease/lib64/libglog.so \
-DCMAKE_INSTALL_PREFIX=/install_libs/brpc \
-DCMAKE_CPP_FLAGS="-fPIC -D_GLIBCXX_USE_CXX11_ABI=1 -DTHREAD_SANITIZER -DDYNAMIC_ANNOTATIONS_ENABLED=1 -fsanitize=thread" \
..
// /v/tsan_demo/tsan_test.cc
#include <chrono>
#include <string>
#include <thread>
#include "brpc/server.h"
#include "butil/endpoint.h"
#include "glog/logging.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
namespace my {
namespace {
class MyTest : public ::testing::Test {
public:
MyTest() = default;
};
TEST_F(MyTest, TSAN_Check) {
LOG(INFO) << "Hello, TSAN!";
}
TEST_F(MyTest, TSAN_Check_brpc) {
LOG(INFO) << "Hello, TSAN brpc!";
butil::ip_t ip = butil::my_ip();
uint16_t port = 12345;
brpc::Server server;
butil::EndPoint end_point = butil::EndPoint(ip, port);
int rc = server.Start(end_point, NULL);
ASSERT_EQ(0, rc);
std::this_thread::sleep_for(std::chrono::seconds(20));
server.Stop(0);
server.Join();
}
} // namespace
} // namespace my
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
::testing::InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS();
}
# 编译
/usr/bin/clang++ -I/v/tsan_demo -I/install_libs/brpc/include -Wno-inconsistent-missing-override -DTHREAD_SANITIZER -DDYNAMIC_ANNOTATIONS_ENABLED=1 -fsanitize=thread -fPIC -g -std=gnu++11 -MD -MT /v/tsan_demo/build_tsan/tsan_test.cc.o -MF /v/tsan_demo/build_tsan/tsan_test.cc.o.d -o /v/tsan_demo/build_tsan/tsan_test.cc.o -c /v/tsan_demo/tsan_test.cc
# 连接
/usr/bin/clang++ -DTHREAD_SANITIZER -DDYNAMIC_ANNOTATIONS_ENABLED=1 -DCOMPILER_CLANG -fsanitize=thread -fPIC -g -fsanitize=thread -pie /v/tsan_demo/build_tsan/tsan_test.cc.o -o /v/tsan_demo/build_tsan/tsan_test -lgtest -lgmock /install_libs/brpc/lib64/libbrpc.a -lprotobuf -lleveldb -lglog -lrt -lssl -lcrypto -ldl -lz -lsnappy -lzstd -llz4 -lbz2 /usr/lib64/libunwind.so -lgflags -lpthread
WARNING: ThreadSanitizer: data race (pid=73930)
Read of size 8 at 0x7b2c00000120 by main thread:
#0 butil::LinkNode<bvar::detail::AgentCombiner<bvar::detail::Sampler*, bvar::detail::Sampler*, bvar::detail::CombineSampler>::Agent>::InsertBefore(butil::LinkNode<bvar::detail::AgentCombiner<bvar::detail::Sampler*, bvar::detail::Sampler*, bvar::detail::CombineSampler>::Agent>*) /v/brpc/incubator-brpc/src/butil/containers/linked_list.h:96:26 (tsan_test+0x2d7c77)
#1 butil::LinkedList<bvar::detail::AgentCombiner<bvar::detail::Sampler*, bvar::detail::Sampler*, bvar::detail::CombineSampler>::Agent>::Append(butil::LinkNode<bvar::detail::AgentCombiner<bvar::detail::Sampler*, bvar::detail::Sampler*, bvar::detail::CombineSampler>::Agent>*) /v/brpc/incubator-brpc/src/butil/containers/linked_list.h:171 (tsan_test+0x2d7c77)
#2 bvar::detail::AgentCombiner<bvar::detail::Sampler*, bvar::detail::Sampler*, bvar::detail::CombineSampler>::get_or_create_tls_agent() /v/brpc/incubator-brpc/src/bvar/detail/combiner.h:310 (tsan_test+0x2d7c77)
#3 bvar::Reducer<bvar::detail::Sampler*, bvar::detail::CombineSampler, bvar::detail::VoidOp>::operator<<(bvar::detail::Sampler* const&) /v/brpc/incubator-brpc/src/bvar/reducer.h:194:35 (tsan_test+0x2d2d88)
#4 bvar::detail::Sampler::schedule() /v/brpc/incubator-brpc/src/bvar/detail/sampler.cpp:201:53 (tsan_test+0x2d2c9a)
#5 bvar::PassiveStatus<int>::expose_impl(butil::BasicStringPiece<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, butil::BasicStringPiece<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, bvar::DisplayFilter) /v/brpc/incubator-brpc/src/bvar/passive_status.h:179:30 (tsan_test+0x28b998)
#6 bvar::Variable::expose(butil::BasicStringPiece<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, bvar::DisplayFilter) /v/brpc/incubator-brpc/src/bvar/variable.h:132:16 (tsan_test+0x178c66)
#7 bvar::PassiveStatus<int>::PassiveStatus(butil::BasicStringPiece<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, int (*)(void*), void*) /v/brpc/incubator-brpc/src/bvar/passive_status.h:85 (tsan_test+0x178c66)
#8 __cxx_global_var_init.1 /v/brpc/incubator-brpc/src/bthread/key.cpp:266 (tsan_test+0x178c66)
#9 _GLOBAL__sub_I_key.cpp /v/brpc/incubator-brpc/src/bthread/key.cpp (tsan_test+0x178c66)
#10 __libc_csu_init <null> (tsan_test+0x596e2c)
Previous write of size 8 at 0x7b2c00000120 by thread T1:
#0 butil::LinkNode<bvar::detail::AgentCombiner<bvar::detail::Sampler*, bvar::detail::Sampler*, bvar::detail::CombineSampler>::Agent>::InsertBefore(butil::LinkNode<bvar::detail::AgentCombiner<bvar::detail::Sampler*, bvar::detail::Sampler*, bvar::detail::CombineSampler>::Agent>*) /v/brpc/incubator-brpc/src/butil/containers/linked_list.h:98:18 (tsan_test+0x2d7c9f)
#1 butil::LinkedList<bvar::detail::AgentCombiner<bvar::detail::Sampler*, bvar::detail::Sampler*, bvar::detail::CombineSampler>::Agent>::Append(butil::LinkNode<bvar::detail::AgentCombiner<bvar::detail::Sampler*, bvar::detail::Sampler*, bvar::detail::CombineSampler>::Agent>*) /v/brpc/incubator-brpc/src/butil/containers/linked_list.h:171 (tsan_test+0x2d7c9f)
#2 bvar::detail::AgentCombiner<bvar::detail::Sampler*, bvar::detail::Sampler*, bvar::detail::CombineSampler>::get_or_create_tls_agent() /v/brpc/incubator-brpc/src/bvar/detail/combiner.h:310 (tsan_test+0x2d7c9f)
#3 bvar::Reducer<bvar::detail::Sampler*, bvar::detail::CombineSampler, bvar::detail::VoidOp>::operator<<(bvar::detail::Sampler* const&) /v/brpc/incubator-brpc/src/bvar/reducer.h:194:35 (tsan_test+0x2d2d88)
#4 bvar::detail::Sampler::schedule() /v/brpc/incubator-brpc/src/bvar/detail/sampler.cpp:201:53 (tsan_test+0x2d5deb)
#5 bvar::PassiveStatus<double>::get_sampler() /v/brpc/incubator-brpc/src/bvar/passive_status.h:146 (tsan_test+0x2d5deb)
#6 bvar::detail::WindowBase<bvar::PassiveStatus<double>, (bvar::SeriesFrequency)1>::WindowBase(bvar::PassiveStatus<double>*, long) /v/brpc/incubator-brpc/src/bvar/window.h:82:25 (tsan_test+0x2d5797)
#7 bvar::PerSecond<bvar::PassiveStatus<double> >::PerSecond(butil::BasicStringPiece<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, bvar::PassiveStatus<double>*, long) /v/brpc/incubator-brpc/src/bvar/window.h:209:11 (tsan_test+0x2d2480)
#8 bvar::detail::SamplerCollector::run() /v/brpc/incubator-brpc/src/bvar/detail/sampler.cpp:143 (tsan_test+0x2d2480)
#9 bvar::detail::SamplerCollector::sampling_thread(void*) /v/brpc/incubator-brpc/src/bvar/detail/sampler.cpp:110:46 (tsan_test+0x2d3839)
Location is heap block of size 168 at 0x7b2c000000b0 allocated by main thread:
#0 operator new(unsigned long) <null> (tsan_test+0x226f57)
#1 butil::GetLeakySingleton<bvar::detail::SamplerCollector>::create_leaky_singleton() /v/brpc/incubator-brpc/src/butil/memory/singleton_on_pthread_once.h:42:14 (tsan_test+0x2d2ed9)
#2 pthread_once <null> (tsan_test+0x1b77df)
#3 bvar::detail::SamplerCollector* butil::get_leaky_singleton<bvar::detail::SamplerCollector>() /v/brpc/incubator-brpc/src/butil/memory/singleton_on_pthread_once.h:60:5 (tsan_test+0x2d2c74)
#4 bvar::detail::Sampler::schedule() /v/brpc/incubator-brpc/src/bvar/detail/sampler.cpp:201 (tsan_test+0x2d2c74)
#5 bvar::PassiveStatus<int>::expose_impl(butil::BasicStringPiece<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, butil::BasicStringPiece<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, bvar::DisplayFilter) /v/brpc/incubator-brpc/src/bvar/passive_status.h:179:30 (tsan_test+0x28b998)
#6 bvar::Variable::expose(butil::BasicStringPiece<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, bvar::DisplayFilter) /v/brpc/incubator-brpc/src/bvar/variable.h:132:16 (tsan_test+0x178c66)
#7 bvar::PassiveStatus<int>::PassiveStatus(butil::BasicStringPiece<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, int (*)(void*), void*) /v/brpc/incubator-brpc/src/bvar/passive_status.h:85 (tsan_test+0x178c66)
#8 __cxx_global_var_init.1 /v/brpc/incubator-brpc/src/bthread/key.cpp:266 (tsan_test+0x178c66)
#9 _GLOBAL__sub_I_key.cpp /v/brpc/incubator-brpc/src/bthread/key.cpp (tsan_test+0x178c66)
#10 __libc_csu_init <null> (tsan_test+0x596e2c)
Thread T1 (tid=73932, running) created by main thread at:
#0 pthread_create <null> (tsan_test+0x1b6fd6)
#1 bvar::detail::SamplerCollector::create_sampling_thread() /v/brpc/incubator-brpc/src/bvar/detail/sampler.cpp:90:24 (tsan_test+0x2d30a0)
#2 bvar::detail::SamplerCollector::SamplerCollector() /v/brpc/incubator-brpc/src/bvar/detail/sampler.cpp:67:9 (tsan_test+0x2d3037)
#3 butil::GetLeakySingleton<bvar::detail::SamplerCollector>::create_leaky_singleton() /v/brpc/incubator-brpc/src/butil/memory/singleton_on_pthread_once.h:42:18 (tsan_test+0x2d2ee4)
#4 pthread_once <null> (tsan_test+0x1b77df)
#5 bvar::detail::SamplerCollector* butil::get_leaky_singleton<bvar::detail::SamplerCollector>() /v/brpc/incubator-brpc/src/butil/memory/singleton_on_pthread_once.h:60:5 (tsan_test+0x2d2c74)
#6 bvar::detail::Sampler::schedule() /v/brpc/incubator-brpc/src/bvar/detail/sampler.cpp:201 (tsan_test+0x2d2c74)
#7 bvar::PassiveStatus<int>::expose_impl(butil::BasicStringPiece<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, butil::BasicStringPiece<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, bvar::DisplayFilter) /v/brpc/incubator-brpc/src/bvar/passive_status.h:179:30 (tsan_test+0x28b998)
#8 bvar::Variable::expose(butil::BasicStringPiece<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, bvar::DisplayFilter) /v/brpc/incubator-brpc/src/bvar/variable.h:132:16 (tsan_test+0x178c66)
#9 bvar::PassiveStatus<int>::PassiveStatus(butil::BasicStringPiece<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, int (*)(void*), void*) /v/brpc/incubator-brpc/src/bvar/passive_status.h:85 (tsan_test+0x178c66)
#10 __cxx_global_var_init.1 /v/brpc/incubator-brpc/src/bthread/key.cpp:266 (tsan_test+0x178c66)
#11 _GLOBAL__sub_I_key.cpp /v/brpc/incubator-brpc/src/bthread/key.cpp (tsan_test+0x178c66)
#12 __libc_csu_init <null> (tsan_test+0x596e2c)
SUMMARY: ThreadSanitizer: data race /v/brpc/incubator-brpc/src/butil/containers/linked_list.h:96:26 in butil::LinkNode<bvar::detail::AgentCombiner<bvar::detail::Sampler*, bvar::detail::Sampler*, bvar::detail::CombineSampler>::Agent>::InsertBefore(butil::LinkNode<bvar::detail::AgentCombiner<bvar::detail::Sampler*, bvar::detail::Sampler*, bvar::detail::CombineSampler>::Agent>*)
Describe the bug (描述bug)
使用Clang,开TSAN编译,生成静态库libbrpc.a,同样开TSAN编译,生成可执行程序,运行程序,TSAN校验报错
To Reproduce (复现方法)
Clang开TSAN编译libbrpc.a
简单的TSAN Check UT:
同样开TSAN,编译连接tsan_test:
Expected behavior (期望行为)
期望行为是UT正常运行, 但是实际会保很多TSAN校验错误:
Versions (各种版本)
OS: Linux 3.10.0-327
Compiler: clang-8
brpc: master分支( 2c98d0a, "Update oncall.md")
protobuf: protobuf-3.17.3
Additional context/screenshots (更多上下文/截图)
