diff options
Diffstat (limited to 'third_party/libwebrtc/webrtc/build/sanitizers')
5 files changed, 572 insertions, 0 deletions
diff --git a/third_party/libwebrtc/webrtc/build/sanitizers/OWNERS b/third_party/libwebrtc/webrtc/build/sanitizers/OWNERS new file mode 100644 index 0000000000..3059b0e42a --- /dev/null +++ b/third_party/libwebrtc/webrtc/build/sanitizers/OWNERS @@ -0,0 +1,4 @@ +glider@chromium.org +eugenis@chromium.org +per-file tsan_suppressions.cc=* +per-file lsan_suppressions.cc=* diff --git a/third_party/libwebrtc/webrtc/build/sanitizers/asan_suppressions.cc b/third_party/libwebrtc/webrtc/build/sanitizers/asan_suppressions.cc new file mode 100644 index 0000000000..df94bc8950 --- /dev/null +++ b/third_party/libwebrtc/webrtc/build/sanitizers/asan_suppressions.cc @@ -0,0 +1,23 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file contains the default suppressions for AddressSanitizer. +// It should only be used under very limited circumstances such as suppressing +// a report caused by an interceptor call in a system-installed library. + +#if defined(ADDRESS_SANITIZER) + +// Please make sure the code below declares a single string variable +// kASanDefaultSuppressions which contains ASan suppressions delimited by +// newlines. +char kASanDefaultSuppressions[] = +// http://crbug.com/178677 +"interceptor_via_lib:libsqlite3.so\n" + +// PLEASE READ ABOVE BEFORE ADDING NEW SUPPRESSIONS. + +// End of suppressions. +; // Please keep this semicolon. + +#endif // ADDRESS_SANITIZER diff --git a/third_party/libwebrtc/webrtc/build/sanitizers/lsan_suppressions.cc b/third_party/libwebrtc/webrtc/build/sanitizers/lsan_suppressions.cc new file mode 100644 index 0000000000..4b75528ad7 --- /dev/null +++ b/third_party/libwebrtc/webrtc/build/sanitizers/lsan_suppressions.cc @@ -0,0 +1,98 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file contains the default suppressions for LeakSanitizer. +// You can also pass additional suppressions via LSAN_OPTIONS: +// LSAN_OPTIONS=suppressions=/path/to/suppressions. Please refer to +// http://dev.chromium.org/developers/testing/leaksanitizer for more info. + +#if defined(LEAK_SANITIZER) + +// Please make sure the code below declares a single string variable +// kLSanDefaultSuppressions which contains LSan suppressions delimited by +// newlines. See http://dev.chromium.org/developers/testing/leaksanitizer +// for the instructions on writing suppressions. +char kLSanDefaultSuppressions[] = + // Intentional leak used as sanity test for Valgrind/memcheck. + "leak:base::ToolsSanityTest_MemoryLeak_Test::TestBody\n" + + // ================ Leaks in third-party code ================ + + // False positives in libfontconfig. http://crbug.com/39050 + "leak:libfontconfig\n" + // eglibc-2.19/string/strdup.c creates false positive leak errors because of + // the same reason as crbug.com/39050. The leak error stack trace, when + // unwind on malloc, includes a call to libfontconfig. But the default stack + // trace is too short in leak sanitizer bot to make the libfontconfig + // suppression works. http://crbug.com/605286 + "leak:__strdup\n" + + // Leaks in Nvidia's libGL. + "leak:libGL.so\n" + + // TODO(eugenis): revisit NSS suppressions after the switch to BoringSSL + // NSS leaks in CertDatabaseNSSTest tests. http://crbug.com/51988 + "leak:net::NSSCertDatabase::ImportFromPKCS12\n" + "leak:net::NSSCertDatabase::ListCerts\n" + "leak:net::NSSCertDatabase::DeleteCertAndKey\n" + "leak:crypto::ScopedTestNSSDB::ScopedTestNSSDB\n" + // Another leak due to not shutting down NSS properly. + // http://crbug.com/124445 + "leak:error_get_my_stack\n" + // The NSS suppressions above will not fire when the fast stack unwinder is + // used, because it can't unwind through NSS libraries. Apply blanket + // suppressions for now. + "leak:libnssutil3\n" + "leak:libnspr4\n" + "leak:libnss3\n" + "leak:libplds4\n" + "leak:libnssckbi\n" + + // XRandR has several one time leaks. + "leak:libxrandr\n" + + // xrandr leak. http://crbug.com/119677 + "leak:XRRFindDisplay\n" + + // http://crbug.com/431213, http://crbug.com/416665 + "leak:gin/object_template_builder.h\n" + + // Leaks in swrast_dri.so. http://crbug.com/540042 + "leak:swrast_dri.so\n" + + // Leak in glibc's gconv caused by fopen(..., "r,ccs=UNICODE") + "leak:__gconv_lookup_cache\n" + + // ================ Leaks in Chromium code ================ + // PLEASE DO NOT ADD SUPPRESSIONS FOR NEW LEAKS. + // Instead, commits that introduce memory leaks should be reverted. + // Suppressing the leak is acceptable in some cases when reverting is + // impossible, i.e. when enabling leak detection for the first time for a + // test target with pre-existing leaks. + + // Small test-only leak in ppapi_unittests. http://crbug.com/258113 + "leak:ppapi::proxy::PPP_Instance_Private_ProxyTest_PPPInstancePrivate_" + "Test\n" + + // http://crbug.com/322671 + "leak:content::SpeechRecognitionBrowserTest::SetUpOnMainThread\n" + + // http://crbug.com/355641 + "leak:TrayAccessibilityTest\n" + + // http://crbug.com/354644 + "leak:CertificateViewerUITest::ShowModalCertificateViewer\n" + + // http://crbug.com/356306 + "leak:service_manager::SetProcessTitleFromCommandLine\n" + + // http://crbug.com/601435 + "leak:mojo/edk/js/handle.h\n" + + // PLEASE READ ABOVE BEFORE ADDING NEW SUPPRESSIONS. + + // End of suppressions. + ; // Please keep this semicolon. + +#endif // LEAK_SANITIZER diff --git a/third_party/libwebrtc/webrtc/build/sanitizers/sanitizer_options.cc b/third_party/libwebrtc/webrtc/build/sanitizers/sanitizer_options.cc new file mode 100644 index 0000000000..e7e427981f --- /dev/null +++ b/third_party/libwebrtc/webrtc/build/sanitizers/sanitizer_options.cc @@ -0,0 +1,181 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// This file contains the default options for various compiler-based dynamic +// tools. + +#include "build/build_config.h" + +#if defined(ADDRESS_SANITIZER) && defined(OS_MACOSX) +#include <crt_externs.h> // for _NSGetArgc, _NSGetArgv +#include <string.h> +#endif // ADDRESS_SANITIZER && OS_MACOSX + +#if defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) || \ + defined(MEMORY_SANITIZER) || defined(THREAD_SANITIZER) || \ + defined(UNDEFINED_SANITIZER) +// Functions returning default options are declared weak in the tools' runtime +// libraries. To make the linker pick the strong replacements for those +// functions from this module, we explicitly force its inclusion by passing +// -Wl,-u_sanitizer_options_link_helper +extern "C" +void _sanitizer_options_link_helper() { } + +// The callbacks we define here will be called from the sanitizer runtime, but +// aren't referenced from the Chrome executable. We must ensure that those +// callbacks are not sanitizer-instrumented, and that they aren't stripped by +// the linker. +#define SANITIZER_HOOK_ATTRIBUTE \ + extern "C" \ + __attribute__((no_sanitize("address", "memory", "thread", "undefined"))) \ + __attribute__((visibility("default"))) \ + __attribute__((used)) +#endif + +#if defined(ADDRESS_SANITIZER) +// Default options for AddressSanitizer in various configurations: +// malloc_context_size=5 - limit the size of stack traces collected by ASan +// for each malloc/free by 5 frames. These stack traces tend to accumulate +// very fast in applications using JIT (v8 in Chrome's case), see +// https://code.google.com/p/address-sanitizer/issues/detail?id=177 +// symbolize=1 - enable in-process symbolization. +// legacy_pthread_cond=1 - run in the libpthread 2.2.5 compatibility mode to +// work around libGL.so using the obsolete API, see +// http://crbug.com/341805. This may break if pthread_cond_t objects are +// accessed by both instrumented and non-instrumented binaries (e.g. if +// they reside in shared memory). This option is going to be deprecated in +// upstream AddressSanitizer and must not be used anywhere except the +// official builds. +// check_printf=1 - check the memory accesses to printf (and other formatted +// output routines) arguments. +// use_sigaltstack=1 - handle signals on an alternate signal stack. Useful +// for stack overflow detection. +// strip_path_prefix=/../../ - prefixes up to and including this +// substring will be stripped from source file paths in symbolized reports +// fast_unwind_on_fatal=1 - use the fast (frame-pointer-based) stack unwinder +// to print error reports. V8 doesn't generate debug info for the JIT code, +// so the slow unwinder may not work properly. +// detect_stack_use_after_return=1 - use fake stack to delay the reuse of +// stack allocations and detect stack-use-after-return errors. +#if defined(OS_LINUX) +#if defined(GOOGLE_CHROME_BUILD) +// Default AddressSanitizer options for the official build. These do not affect +// tests on buildbots (which don't set GOOGLE_CHROME_BUILD) or non-official +// Chromium builds. +const char kAsanDefaultOptions[] = + "legacy_pthread_cond=1 malloc_context_size=5 " + "symbolize=1 check_printf=1 use_sigaltstack=1 detect_leaks=0 " + "strip_path_prefix=/../../ fast_unwind_on_fatal=1 " + "allow_user_segv_handler=1 "; +#else +// Default AddressSanitizer options for buildbots and non-official builds. +const char* kAsanDefaultOptions = + "symbolize=1 check_printf=1 use_sigaltstack=1 " + "detect_leaks=0 strip_path_prefix=/../../ fast_unwind_on_fatal=1 " + "detect_stack_use_after_return=1 " + "allow_user_segv_handler=1 "; +#endif // GOOGLE_CHROME_BUILD + +#elif defined(OS_MACOSX) +const char *kAsanDefaultOptions = + "check_printf=1 use_sigaltstack=1 " + "strip_path_prefix=/../../ fast_unwind_on_fatal=1 " + "detect_stack_use_after_return=1 detect_odr_violation=0 "; +#endif // OS_LINUX + +#if defined(OS_LINUX) || defined(OS_MACOSX) +// Allow NaCl to override the default asan options. +extern const char* kAsanDefaultOptionsNaCl; +__attribute__((weak)) const char* kAsanDefaultOptionsNaCl = nullptr; + +SANITIZER_HOOK_ATTRIBUTE const char *__asan_default_options() { + if (kAsanDefaultOptionsNaCl) + return kAsanDefaultOptionsNaCl; + return kAsanDefaultOptions; +} + +extern char kASanDefaultSuppressions[]; + +SANITIZER_HOOK_ATTRIBUTE const char *__asan_default_suppressions() { + return kASanDefaultSuppressions; +} +#endif // OS_LINUX || OS_MACOSX +#endif // ADDRESS_SANITIZER + +#if defined(THREAD_SANITIZER) && defined(OS_LINUX) +// Default options for ThreadSanitizer in various configurations: +// detect_deadlocks=1 - enable deadlock (lock inversion) detection. +// second_deadlock_stack=1 - more verbose deadlock reports. +// report_signal_unsafe=0 - do not report async-signal-unsafe functions +// called from signal handlers. +// report_thread_leaks=0 - do not report unjoined threads at the end of +// the program execution. +// print_suppressions=1 - print the list of matched suppressions. +// history_size=7 - make the history buffer proportional to 2^7 (the maximum +// value) to keep more stack traces. +// strip_path_prefix=/../../ - prefixes up to and including this +// substring will be stripped from source file paths in symbolized reports. +const char kTsanDefaultOptions[] = + "detect_deadlocks=1 second_deadlock_stack=1 report_signal_unsafe=0 " + "report_thread_leaks=0 print_suppressions=1 history_size=7 " + "strict_memcmp=0 strip_path_prefix=/../../ "; + +SANITIZER_HOOK_ATTRIBUTE const char *__tsan_default_options() { + return kTsanDefaultOptions; +} + +extern char kTSanDefaultSuppressions[]; + +SANITIZER_HOOK_ATTRIBUTE const char *__tsan_default_suppressions() { + return kTSanDefaultSuppressions; +} + +#endif // THREAD_SANITIZER && OS_LINUX + +#if defined(MEMORY_SANITIZER) +// Default options for MemorySanitizer: +// intercept_memcmp=0 - do not detect uninitialized memory in memcmp() calls. +// Pending cleanup, see http://crbug.com/523428 +// strip_path_prefix=/../../ - prefixes up to and including this +// substring will be stripped from source file paths in symbolized reports. +const char kMsanDefaultOptions[] = + "intercept_memcmp=0 strip_path_prefix=/../../ "; + +SANITIZER_HOOK_ATTRIBUTE const char *__msan_default_options() { + return kMsanDefaultOptions; +} + +#endif // MEMORY_SANITIZER + +#if defined(LEAK_SANITIZER) +// Default options for LeakSanitizer: +// print_suppressions=1 - print the list of matched suppressions. +// strip_path_prefix=/../../ - prefixes up to and including this +// substring will be stripped from source file paths in symbolized reports. +const char kLsanDefaultOptions[] = + "print_suppressions=1 strip_path_prefix=/../../ "; + +SANITIZER_HOOK_ATTRIBUTE const char *__lsan_default_options() { + return kLsanDefaultOptions; +} + +extern char kLSanDefaultSuppressions[]; + +SANITIZER_HOOK_ATTRIBUTE const char *__lsan_default_suppressions() { + return kLSanDefaultSuppressions; +} + +#endif // LEAK_SANITIZER + +#if defined(UNDEFINED_SANITIZER) +// Default options for UndefinedBehaviorSanitizer: +// print_stacktrace=1 - print the stacktrace when UBSan reports an error. +const char kUbsanDefaultOptions[] = + "print_stacktrace=1 strip_path_prefix=/../../ "; + +SANITIZER_HOOK_ATTRIBUTE const char* __ubsan_default_options() { + return kUbsanDefaultOptions; +} + +#endif // UNDEFINED_SANITIZER diff --git a/third_party/libwebrtc/webrtc/build/sanitizers/tsan_suppressions.cc b/third_party/libwebrtc/webrtc/build/sanitizers/tsan_suppressions.cc new file mode 100644 index 0000000000..e357a9ef0d --- /dev/null +++ b/third_party/libwebrtc/webrtc/build/sanitizers/tsan_suppressions.cc @@ -0,0 +1,266 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file contains the default suppressions for ThreadSanitizer. +// You can also pass additional suppressions via TSAN_OPTIONS: +// TSAN_OPTIONS=suppressions=/path/to/suppressions. Please refer to +// http://dev.chromium.org/developers/testing/threadsanitizer-tsan-v2 +// for more info. + +#if defined(THREAD_SANITIZER) + +// Please make sure the code below declares a single string variable +// kTSanDefaultSuppressions contains TSan suppressions delimited by newlines. +// See http://dev.chromium.org/developers/testing/threadsanitizer-tsan-v2 +// for the instructions on writing suppressions. +char kTSanDefaultSuppressions[] = + // False positives in libflashplayer.so and libglib.so. Since we don't + // instrument them, we cannot reason about the synchronization in them. + "race:libflashplayer.so\n" + "race:libglib*.so\n" + + // Intentional race in ToolsSanityTest.DataRace in base_unittests. + "race:base/tools_sanity_unittest.cc\n" + + // Data race on WatchdogCounter [test-only]. + "race:base/threading/watchdog_unittest.cc\n" + + // Races in libevent, http://crbug.com/23244. + "race:libevent/event.c\n" + + // http://crbug.com/84094. + "race:sqlite3StatusSet\n" + "race:pcache1EnforceMaxPage\n" + "race:pcache1AllocPage\n" + + // http://crbug.com/102327. + // Test-only race, won't fix. + "race:tracked_objects::ThreadData::ShutdownSingleThreadedCleanup\n" + + // http://crbug.com/120808 + "race:base/threading/watchdog.cc\n" + + // http://crbug.com/157586 + "race:third_party/libvpx/source/libvpx/vp8/decoder/threading.c\n" + + // http://crbug.com/158718 + "race:third_party/ffmpeg/libavcodec/pthread.c\n" + "race:third_party/ffmpeg/libavcodec/pthread_frame.c\n" + "race:third_party/ffmpeg/libavcodec/vp8.c\n" + "race:third_party/ffmpeg/libavutil/mem.c\n" + "race:*HashFrameForTesting\n" + "race:third_party/ffmpeg/libavcodec/h264pred.c\n" + "race:media::ReleaseData\n" + + // http://crbug.com/158922 + "race:third_party/libvpx/source/libvpx/vp8/encoder/*\n" + "race:third_party/libvpx/source/libvpx/vp9/encoder/*\n" + + // http://crbug.com/189177 + "race:thread_manager\n" + "race:v8::Locker::Initialize\n" + + // http://crbug.com/239359 + "race:media::TestInputCallback::OnData\n" + + // http://crbug.com/244368 + "race:skia::BeginPlatformPaint\n" + + // http://crbug.com/244385 + "race:unixTempFileDir\n" + + // http://crbug.com/244755 + "race:v8::internal::Zone::NewExpand\n" + "race:TooLateToEnableNow\n" + "race:adjust_segment_bytes_allocated\n" + + // http://crbug.com/244774 + "race:webrtc::RTPReceiver::ProcessBitrate\n" + "race:webrtc::RTPSender::ProcessBitrate\n" + "race:webrtc::VideoCodingModuleImpl::Decode\n" + "race:webrtc::RTPSender::SendOutgoingData\n" + "race:webrtc::VP8EncoderImpl::GetEncodedPartitions\n" + "race:webrtc::VP8EncoderImpl::Encode\n" + "race:webrtc::ViEEncoder::DeliverFrame\n" + "race:webrtc::vcm::VideoReceiver::Decode\n" + "race:webrtc::VCMReceiver::FrameForDecoding\n" + "race:*trace_event_unique_catstatic*\n" + + // http://crbug.com/244856 + "race:AutoPulseLock\n" + + // http://crbug.com/246968 + "race:webrtc::VideoCodingModuleImpl::RegisterPacketRequestCallback\n" + + // http://crbug.com/246974 + "race:content::GpuWatchdogThread::CheckArmed\n" + + // http://crbug.com/257396 + "race:base::trace_event::" + "TraceEventTestFixture_TraceSamplingScope_Test::TestBody\n" + + // http://crbug.com/258479 + "race:SamplingStateScope\n" + "race:g_trace_state\n" + + // http://crbug.com/258499 + "race:third_party/skia/include/core/SkRefCnt.h\n" + + // http://crbug.com/268924 + "race:base::g_power_monitor\n" + "race:base::PowerMonitor::PowerMonitor\n" + "race:base::PowerMonitor::AddObserver\n" + "race:base::PowerMonitor::RemoveObserver\n" + "race:base::PowerMonitor::IsOnBatteryPower\n" + + // http://crbug.com/258935 + "race:base::Thread::StopSoon\n" + + // http://crbug.com/272095 + "race:base::g_top_manager\n" + + // http://crbug.com/308590 + "race:CustomThreadWatcher::~CustomThreadWatcher\n" + + // http://crbug.com/310851 + "race:net::ProxyResolverV8Tracing::Job::~Job\n" + + // http://crbug.com/327330 + "race:PrepareTextureMailbox\n" + "race:cc::LayerTreeHost::PaintLayerContents\n" + + // http://crbug.com/476529 + "deadlock:cc::VideoLayerImpl::WillDraw\n" + + // http://crbug.com/328826 + "race:gLCDOrder\n" + "race:gLCDOrientation\n" + + // http://crbug.com/328868 + "race:PR_Lock\n" + + // http://crbug.com/333244 + "race:content::" + "VideoCaptureImplTest::MockVideoCaptureImpl::~MockVideoCaptureImpl\n" + + // http://crbug.com/333871 + "race:v8::internal::Interface::NewValue()::value_interface\n" + "race:v8::internal::IsMinusZero(double)::minus_zero\n" + "race:v8::internal::FastCloneShallowObjectStub::" + "InitializeInterfaceDescriptor\n" + "race:v8::internal::KeyedLoadStubCompiler::registers\n" + "race:v8::internal::KeyedStoreStubCompiler::registers()::registers\n" + "race:v8::internal::KeyedLoadFastElementStub::" + "InitializeInterfaceDescriptor\n" + "race:v8::internal::KeyedStoreFastElementStub::" + "InitializeInterfaceDescriptor\n" + "race:v8::internal::LoadStubCompiler::registers\n" + "race:v8::internal::StoreStubCompiler::registers\n" + "race:v8::internal::HValue::LoopWeight\n" + + // http://crbug.com/334140 + "race:CommandLine::HasSwitch\n" + "race:CommandLine::current_process_commandline_\n" + "race:CommandLine::GetSwitchValueASCII\n" + + // http://crbug.com/338675 + "race:blink::s_platform\n" + "race:content::" + "RendererWebKitPlatformSupportImpl::~RendererWebKitPlatformSupportImpl\n" + + // http://crbug.com/347534 + "race:v8::internal::V8::TearDown\n" + + // http://crbug.com/347538 + "race:sctp_timer_start\n" + + // http://crbug.com/347553 + "race:blink::WebString::reset\n" + + // http://crbug.com/348511 + "race:webrtc::acm1::AudioCodingModuleImpl::PlayoutData10Ms\n" + + // http://crbug.com/348982 + "race:cricket::P2PTransportChannel::OnConnectionDestroyed\n" + "race:cricket::P2PTransportChannel::AddConnection\n" + + // http://crbug.com/348984 + "race:sctp_express_handle_sack\n" + "race:system_base_info\n" + + // https://code.google.com/p/v8/issues/detail?id=3143 + "race:v8::internal::FLAG_track_double_fields\n" + + // http://crbug.com/374135 + "race:media::AlsaWrapper::PcmWritei\n" + + // False positive in libc's tzset_internal, http://crbug.com/379738. + "race:tzset_internal\n" + + // http://crbug.com/380554 + "deadlock:g_type_add_interface_static\n" + + // http:://crbug.com/386385 + "race:content::AppCacheStorageImpl::DatabaseTask::CallRunCompleted\n" + + // http://crbug.com/388730 + "race:g_next_user_script_id\n" + + // http://crbug.com/397022 + "deadlock:" + "base::trace_event::TraceEventTestFixture_ThreadOnceBlocking_Test::" + "TestBody\n" + + // http://crbug.com/415472 + "deadlock:base::trace_event::TraceLog::GetCategoryGroupEnabled\n" + + // http://crbug.com/490856 + "deadlock:content::TracingControllerImpl::SetEnabledOnFileThread\n" + + // https://code.google.com/p/skia/issues/detail?id=3294 + "race:SkBaseMutex::acquire\n" + + // https://crbug.com/430533 + "race:TileTaskGraphRunner::Run\n" + + // Lock inversion in third party code, won't fix. + // https://crbug.com/455638 + "deadlock:dbus::Bus::ShutdownAndBlock\n" + + // https://crbug.com/459429 + "race:randomnessPid\n" + + // https://crbug.com/454655 + "race:content::BrowserTestBase::PostTaskToInProcessRendererAndWait\n" + + // https://crbug.com/569682 + "race:blink::ThreadState::visitStackRoots\n" + + // http://crbug.com/582274 + "race:usrsctp_close\n" + + // http://crbug.com/633145 + "race:third_party/libjpeg_turbo/simd/jsimd_x86_64.c\n" + + // http://crbug.com/587199 + "race:base::TimerTest_OneShotTimer_CustomTaskRunner_Test::TestBody\n" + + // http://crbug.com/v8/6065 + "race:net::(anonymous namespace)::ProxyResolverV8TracingImpl::RequestImpl" + "::~RequestImpl()\n" + + // http://crbug.com/691029 + "deadlock:libGLX.so*\n" + + // http://crbug.com/719633 + "race:crypto::EnsureNSSInit()\n" + + // http://crbug.com/695929 + "race:base::i18n::IsRTL\n" + "race:base::i18n::SetICUDefaultLocale\n" + + // End of suppressions. + ; // Please keep this semicolon. + +#endif // THREAD_SANITIZER |