You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kudu.apache.org by gr...@apache.org on 2018/08/24 20:57:48 UTC

kudu git commit: [build] Move default sanitizer options into build from shell scripts

Repository: kudu
Updated Branches:
  refs/heads/master d3ef58b71 -> a8d088e11


[build] Move default sanitizer options into build from shell scripts

This moves the sanitizer options and suppressions
from the build scripts using
TSAN_OPTIONS/LSAN_OPTIONS/etc into the build
and linked at build time.

This ensures the same configurations are used for
C++ and Java tests.

Change-Id: I9eab2d3ef0b107ae9a4e971bf8a6514bf425f645
Reviewed-on: http://gerrit.cloudera.org:8080/11176
Reviewed-by: Adar Dembo <ad...@cloudera.com>
Tested-by: Grant Henke <gr...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/kudu/repo
Commit: http://git-wip-us.apache.org/repos/asf/kudu/commit/a8d088e1
Tree: http://git-wip-us.apache.org/repos/asf/kudu/tree/a8d088e1
Diff: http://git-wip-us.apache.org/repos/asf/kudu/diff/a8d088e1

Branch: refs/heads/master
Commit: a8d088e11b8b901a91e4820dcfdca9537a1e801a
Parents: d3ef58b
Author: Grant Henke <gr...@apache.org>
Authored: Thu Aug 9 10:30:46 2018 -0500
Committer: Grant Henke <gr...@apache.org>
Committed: Fri Aug 24 20:57:19 2018 +0000

----------------------------------------------------------------------
 CMakeLists.txt                            |  33 +++-
 README.adoc                               |  29 +---
 build-support/dist_test.py                |   2 -
 build-support/jenkins/build-and-test.sh   |   1 -
 build-support/lsan-suppressions.txt       |  23 ---
 build-support/run-test.sh                 |  19 ---
 build-support/run_dist_test.py            |  12 +-
 build-support/tsan-suppressions.txt       | 110 -------------
 src/kudu/benchmarks/CMakeLists.txt        |  18 +--
 src/kudu/cfile/CMakeLists.txt             |   2 +-
 src/kudu/client/CMakeLists.txt            |   6 +-
 src/kudu/clock/CMakeLists.txt             |   3 +-
 src/kudu/codegen/CMakeLists.txt           |   2 +-
 src/kudu/common/CMakeLists.txt            |   2 +-
 src/kudu/consensus/CMakeLists.txt         |   6 +-
 src/kudu/experiments/CMakeLists.txt       |   8 +-
 src/kudu/fs/CMakeLists.txt                |   2 +-
 src/kudu/hms/CMakeLists.txt               |   5 +-
 src/kudu/integration-tests/CMakeLists.txt |   2 +-
 src/kudu/master/CMakeLists.txt            |   4 +-
 src/kudu/mini-cluster/CMakeLists.txt      |   2 +-
 src/kudu/rpc/CMakeLists.txt               |   5 +-
 src/kudu/security/CMakeLists.txt          |   5 +-
 src/kudu/server/CMakeLists.txt            |   2 +-
 src/kudu/tablet/CMakeLists.txt            |   4 +-
 src/kudu/tools/CMakeLists.txt             |   6 +-
 src/kudu/tserver/CMakeLists.txt           |  10 +-
 src/kudu/util/CMakeLists.txt              |  25 ++-
 src/kudu/util/sanitizer_options.cc        | 205 +++++++++++++++++++++++++
 29 files changed, 312 insertions(+), 241 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kudu/blob/a8d088e1/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 559e3e2..bfdacd5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -397,7 +397,7 @@ if (${KUDU_USE_TSAN})
 endif()
 
 
-if ("${KUDU_USE_UBSAN}" OR "${KUDU_USE_ASAN}" OR "${KUDU_USE_TSAN}")
+if ("${KUDU_USE_ASAN}" OR "${KUDU_USE_TSAN}" OR "${KUDU_USE_UBSAN}")
   # GCC 4.8 and 4.9 (latest as of this writing) don't allow you to specify a
   # sanitizer blacklist.
   if("${COMPILER_FAMILY}" STREQUAL "clang")
@@ -1211,13 +1211,14 @@ if (NOT NO_TESTS)
 endif()
 
 # The tests as well as any binaries which are run as subprocesses by tests (eg tserver,
-# master, and the 'kudu' CLI tool) need to link this in. We have to set it
-# here so it's accessible by all targets.
-#
-# OSX doesn't support the linker flag below, but also has a new enough krb5 that the
-# override library isn't necessary.
+# master, and the 'kudu' CLI tool) need to link these in. We have to set them
+# here so they are accessible by all targets.
 if (NOT APPLE)
-set(KRB5_REALM_OVERRIDE -Wl,--undefined=krb5_realm_override_loaded krb5_realm_override)
+  set(SANITIZER_OPTIONS_OVERRIDE -Wl,-u_sanitizer_options_link_helper sanitizer_options)
+  set(KRB5_REALM_OVERRIDE -Wl,--undefined=krb5_realm_override_loaded krb5_realm_override)
+else()
+  set(SANITIZER_OPTIONS_OVERRIDE -Wl,-U,_sanitizer_options_link_helper sanitizer_options)
+  set(KRB5_REALM_OVERRIDE -Wl,-U,krb5_realm_override_loaded krb5_realm_override)
 endif()
 
 ## Boost
@@ -1273,9 +1274,25 @@ endif()
 ############################################################
 # Linker setup
 ############################################################
-set(KUDU_MIN_TEST_LIBS kudu_test_main kudu_test_util ${KUDU_BASE_LIBS})
+
+set(KUDU_MIN_TEST_LIBS ${KUDU_BASE_LIBS} kudu_test_main kudu_test_util)
+# Prepend SANITIZER_OPTIONS_OVERRIDE if this is a sanitizer build.
+# SANITIZER_OPTIONS_OVERRIDE needs to be linked first so that it is statically
+# linked to the test binaries directly. Otherwise the weakly linked default
+# implementations coul be be used when running tests.
+if ("${KUDU_USE_ASAN}" OR "${KUDU_USE_TSAN}" OR "${KUDU_USE_UBSAN}")
+  list(INSERT KUDU_MIN_TEST_LIBS 0 ${SANITIZER_OPTIONS_OVERRIDE})
+endif()
 set(KUDU_TEST_LINK_LIBS ${KUDU_MIN_TEST_LIBS})
 
+# This macro initializes KUDU_MIN_TEST_LIBS to KUDU_MIN_TEST_LIBS and
+# appends the passed list of libraries to the end. This ensures that
+# KUDU_MIN_TEST_LIBS is linked first.
+macro(SET_KUDU_TEST_LINK_LIBS)
+  set(KUDU_TEST_LINK_LIBS ${KUDU_MIN_TEST_LIBS})
+  list(APPEND KUDU_TEST_LINK_LIBS ${ARGN})
+endmacro()
+
 # Use "thin archives" for our static libraries. We only use static libraries
 # internal to our own build, so thin ones are just as good and much smaller.
 if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")

http://git-wip-us.apache.org/repos/asf/kudu/blob/a8d088e1/README.adoc
----------------------------------------------------------------------
diff --git a/README.adoc b/README.adoc
index 22220d8..04215a4 100644
--- a/README.adoc
+++ b/README.adoc
@@ -121,7 +121,8 @@ $ mkdir -p build/asan
 $ cd build/asan
 $ CC=../../thirdparty/clang-toolchain/bin/clang \
   CXX=../../thirdparty/clang-toolchain/bin/clang++ \
-  cmake -DKUDU_USE_ASAN=1 ../..
+  ./../thirdparty/installed/common/bin/cmake \
+  -DKUDU_USE_ASAN=1 ../..
 $ make -j8
 $ ctest -j8
 ----
@@ -173,34 +174,12 @@ $ mkdir -p build/tsan
 $ cd build/tsan
 $ CC=../../thirdparty/clang-toolchain/bin/clang \
     CXX=../../thirdparty/clang-toolchain/bin/clang++ \
-    cmake -DKUDU_USE_TSAN=1 ../..
+    ../../thirdparty/installed/common/bin/cmake \
+    -DKUDU_USE_TSAN=1 ../..
 $ make -j8
 $ ctest -j8
 ----
 
-. Enabling TSAN supressions while running tests
-[NOTE]
-====
-Note that we rely on a list of runtime suppressions in _build-support/tsan-suppressions.txt_.
-If you simply run a unit test like _build/tsan/bin/foo-test_, you won't get these suppressions.
-Instead, use a command like:
-
-[source,bash]
-----
-$ ctest -R foo-test
-----
-
-or
-
-[source,bash]
-----
-$ build-support/run-test.sh build/tsan/bin/foo-test [--test-arguments-here]
-----
-
-...and then view the logs in _build/tsan/test-logs/_
-
-====
-
 TSAN may truncate a few lines of the stack trace when reporting where the error
 is. This can be bewildering. It's documented for TSANv1 here:
 http://code.google.com/p/data-race-test/wiki/ThreadSanitizerAlgorithm

http://git-wip-us.apache.org/repos/asf/kudu/blob/a8d088e1/build-support/dist_test.py
----------------------------------------------------------------------
diff --git a/build-support/dist_test.py b/build-support/dist_test.py
index 01ab478..def5dff 100755
--- a/build-support/dist_test.py
+++ b/build-support/dist_test.py
@@ -76,8 +76,6 @@ DEPS_FOR_ALL = \
     ["build-support/stacktrace_addr2line.pl",
      "build-support/run-test.sh",
      "build-support/run_dist_test.py",
-     "build-support/tsan-suppressions.txt",
-     "build-support/lsan-suppressions.txt",
      "build-support/java-home-candidates.txt",
 
      # The LLVM symbolizer is necessary for suppressions to work

http://git-wip-us.apache.org/repos/asf/kudu/blob/a8d088e1/build-support/jenkins/build-and-test.sh
----------------------------------------------------------------------
diff --git a/build-support/jenkins/build-and-test.sh b/build-support/jenkins/build-and-test.sh
index 83af078..756a2af 100755
--- a/build-support/jenkins/build-and-test.sh
+++ b/build-support/jenkins/build-and-test.sh
@@ -376,7 +376,6 @@ if [ "$BUILD_JAVA" == "1" ]; then
   export JAVA_HOME=$JAVA8_HOME
   export PATH=$JAVA_HOME/bin:$PATH
   pushd $SOURCE_ROOT/java
-  export TSAN_OPTIONS="$TSAN_OPTIONS suppressions=$SOURCE_ROOT/build-support/tsan-suppressions.txt history_size=7"
   set -x
 
   # Run the full Maven build.

http://git-wip-us.apache.org/repos/asf/kudu/blob/a8d088e1/build-support/lsan-suppressions.txt
----------------------------------------------------------------------
diff --git a/build-support/lsan-suppressions.txt b/build-support/lsan-suppressions.txt
deleted file mode 100644
index dbf8dda..0000000
--- a/build-support/lsan-suppressions.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-# False positive from atexit() registration in libc
-leak:*__new_exitfn*
-
-# False positive from krb5 < 1.12
-# Fixed by upstream commit 379d39c17b8930718e98185a5b32a0f7f3e3b4b6
-leak:krb5_authdata_import_attributes

http://git-wip-us.apache.org/repos/asf/kudu/blob/a8d088e1/build-support/run-test.sh
----------------------------------------------------------------------
diff --git a/build-support/run-test.sh b/build-support/run-test.sh
index bd33b6b..541d6f7 100755
--- a/build-support/run-test.sh
+++ b/build-support/run-test.sh
@@ -112,25 +112,6 @@ else
   pipe_cmd=cat
 fi
 
-# Suppressions require symbolization. We'll default to using the symbolizer in
-# thirdparty.
-if [ -z "$ASAN_SYMBOLIZER_PATH" ]; then
-  export ASAN_SYMBOLIZER_PATH=$SOURCE_ROOT/thirdparty/installed/uninstrumented/bin/llvm-symbolizer
-fi
-
-# Configure TSAN (ignored if this isn't a TSAN build).
-TSAN_OPTIONS="$TSAN_OPTIONS suppressions=$SOURCE_ROOT/build-support/tsan-suppressions.txt"
-TSAN_OPTIONS="$TSAN_OPTIONS history_size=7"
-#   Flush TSAN memory every 10 seconds - this prevents RSS blowup in unit tests
-#   which can cause tests to get killed by the OOM killer.
-TSAN_OPTIONS="$TSAN_OPTIONS flush_memory_ms=10000"
-TSAN_OPTIONS="$TSAN_OPTIONS external_symbolizer_path=$ASAN_SYMBOLIZER_PATH"
-export TSAN_OPTIONS
-
-# Set up suppressions for LeakSanitizer
-LSAN_OPTIONS="$LSAN_OPTIONS suppressions=$SOURCE_ROOT/build-support/lsan-suppressions.txt"
-export LSAN_OPTIONS
-
 # Set a 15-minute timeout for tests run via 'make test'.
 # This keeps our jenkins builds from hanging in the case that there's
 # a deadlock or anything.

http://git-wip-us.apache.org/repos/asf/kudu/blob/a8d088e1/build-support/run_dist_test.py
----------------------------------------------------------------------
diff --git a/build-support/run_dist_test.py b/build-support/run_dist_test.py
index 624ec80..2105ff6 100755
--- a/build-support/run_dist_test.py
+++ b/build-support/run_dist_test.py
@@ -136,6 +136,16 @@ def main():
   fixup_rpaths(os.path.join(ROOT, "build"))
   fixup_rpaths(os.path.join(ROOT, "thirdparty"))
 
+  # Override the external_symbolizer_path to use a valid path on the dist-test
+  # machine. The external_symbolizer_path defined during the build and
+  # used in sanitizer_options.cc is not valid because it's an absolute path on
+  # the build machine.
+  symbolizer_path = os.path.join(ROOT, "thirdparty/installed/uninstrumented/bin/llvm-symbolizer")
+  for sanitizer in ["ASAN", "LSAN", "MSAN", "TSAN", "UBSAN"]:
+    var_name = sanitizer + "_OPTIONS"
+    if "external_symbolizer_path=" not in os.environ.get(var_name, ""):
+      env[var_name] = os.environ.get(var_name, "") + " external_symbolizer_path=" + symbolizer_path
+
   # Add environment variables for Java dependencies. These environment variables
   # are used in mini_hms.cc.
   env['HIVE_HOME'] = glob.glob(os.path.join(ROOT, "thirdparty/src/hive-*"))[0]
@@ -152,8 +162,6 @@ def main():
   test_tmpdir = os.path.abspath(os.path.join(ROOT, "test-tmp"))
   env['TEST_TMPDIR'] = test_tmpdir
 
-  env['ASAN_SYMBOLIZER_PATH'] = os.path.join(ROOT, "thirdparty/installed/uninstrumented/bin/llvm-symbolizer")
-
   stdout = None
   stderr = None
   if options.test_language == 'cpp':

http://git-wip-us.apache.org/repos/asf/kudu/blob/a8d088e1/build-support/tsan-suppressions.txt
----------------------------------------------------------------------
diff --git a/build-support/tsan-suppressions.txt b/build-support/tsan-suppressions.txt
deleted file mode 100644
index f8b9a7e..0000000
--- a/build-support/tsan-suppressions.txt
+++ /dev/null
@@ -1,110 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-
-# libunwind uses some double-checked locking which isn't perfectly safe.
-# Reported at http://savannah.nongnu.org/bugs/index.php?42677
-#
-# With TSAN in clang 3.5, it's the init() function that's flagged as a data
-# race (not local_addr_space_init()), due to the former calling sigfillset()
-# on an unprotected global variable. Although init() calls local_addr_space_init(),
-# it can sometimes be eliminated from the call stack by inlining or a tail-call
-# optimization, so adding the suppression on both is necessary.
-race:_ULx86_64_init
-race:_ULx86_64_local_addr_space_init
-
-# TODO(todd) After upgrading to clang 6.0, libunwind's cache is getting
-# flagged as unsafe.
-race:_ULx86_64_step
-
-# libev uses some lock-free synchronization, but doesn't have TSAN annotations.
-race:epoll_ctl
-
-# TSAN complains about data races on the global signals variable in
-# ev_feed_signal and spoiled errno in ev_sighandler. Both are probably noise.
-race:ev_sighandler
-
-# See https://github.com/google/glog/issues/80 for a general list of TSAN
-# issues in glog.
-# 1. glog's fatal signal handler isn't signal-safe -- it allocates memory.
-#    This isn't great, but nothing we can do about it. See
-#    https://code.google.com/p/google-glog/issues/detail?id=191
-# 2. LOG(FATAL) from multiple threads can also end up triggering a TSAN error.
-# 3. g_now_entering in stacktrace_libunwind-inl.h is reset to false without
-#    a Release_Store.
-# 4. glog's ANNOTATE_BENIGN_RACE macro doesn't do anything.
-# 5. Mutex::is_safe_ is accessed in an unsafe way.
-# 6. vlocal__ is access in an unsafe way at every VLOG() or VLOG_IS_ON()
-#    call-site.
-signal:logging_fail
-race:google::LogMessage::Init
-race:google::GetStackTrace
-race:google::InitVLOG3__
-race:glog_internal_namespace_::Mutex
-race:vlocal__
-
-# gflags variables are accessed without synchronization, but FlagSaver and other
-# APIs acquire locks when accessing them. This should be safe on x86 for
-# primitive flag types, but not for string flags, which is why fLS is omitted.
-race:fLB::
-race:fLD::
-race:fLI::
-race:fLI64::
-race:fLU64::
-
-# This method in Boost's UUID library operates on static state with impunity,
-# triggering (harmless) data races in TSAN when boost::uuids::random_generator
-# instances are created across threads (see kudu::ObjectIdGenerator).
-race:boost::uuids::detail::seed_rng::sha1_random_digest_
-
-# Squeasel uses ctx->stop_flag to synchronize stopping. It always sets it with
-# the context lock held, but sometimes reads it without the context lock. This
-# should be safe on x86, but is nonetheless flagged by TSAN.
-race:sq_stop
-
-# Squeasel reads and frees ctx->listening_sockets without taking any locks. This
-# may be an unsafe race.
-race:close_all_listening_sockets
-
-# ------------------------------------------------------------
-# Known bugs below. As these JIRAs are resolved, please remove the relevant
-# suppression.
-# ------------------------------------------------------------
-
-# KUDU-1283: TSAN warning from consensus OpId
-race:kudu::consensus::OpId::CopyFrom
-
-# KUDU-186: sketchy synchronization in catalog manager
-race:kudu::master::CatalogManager::Shutdown
-race:kudu::master::CatalogManagerBgTasks::Shutdown
-race:kudu::master::CatalogManager::~CatalogManager
-
-# KUDU-574: raft_consensus_quorum-test race on LocalTestPeerProxy destruction
-race:kudu::consensus::LocalTestPeerProxy::~LocalTestPeerProxy
-
-# KUDU-569: unsynchronized access to 'state_', 'acceptor_pools_', in
-# GetBoundAddresses()
-race:kudu::Webserver::GetBoundAddresses
-race:kudu::RpcServer::GetBoundAddresses
-
-# KUDU-2439: OpenSSL 1.1's atexit() handler may destroy global state while a
-# Messenger is shutting down and still accessing that state. See
-# https://github.com/openssl/openssl/issues/6214 for more details.
-#
-# This is carried out by OPENSSL_cleanup, but TSAN's unwinder doesn't
-# include any stack frame above the libcrypto lock destruction or memory release
-# call for some reason, so we have to do something more generic.
-called_from_lib:libcrypto.so

http://git-wip-us.apache.org/repos/asf/kudu/blob/a8d088e1/src/kudu/benchmarks/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/kudu/benchmarks/CMakeLists.txt b/src/kudu/benchmarks/CMakeLists.txt
index 28825dc..0295019 100644
--- a/src/kudu/benchmarks/CMakeLists.txt
+++ b/src/kudu/benchmarks/CMakeLists.txt
@@ -32,29 +32,29 @@ target_link_libraries(tpch
 # tpch1
 add_executable(tpch1 tpch/tpch1.cc)
 target_link_libraries(tpch1
-  tpch
-  ${KUDU_TEST_LINK_LIBS})
+  ${KUDU_MIN_TEST_LIBS}
+  tpch)
 
 # tpch_real_world
 add_executable(tpch_real_world tpch/tpch_real_world.cc)
 target_link_libraries(tpch_real_world
-  tpch
-  ${KUDU_TEST_LINK_LIBS})
+  ${KUDU_MIN_TEST_LIBS}
+  tpch)
 
 # rle
 add_executable(rle rle.cc)
 target_link_libraries(rle
-  kudu_util
-  ${KUDU_TEST_LINK_LIBS})
+  ${KUDU_MIN_TEST_LIBS}
+  kudu_util)
 
 # Disabled on macOS since it relies on fdatasync() and sync_file_range().
 if(NOT APPLE)
   add_executable(wal_hiccup wal_hiccup.cc)
   target_link_libraries(wal_hiccup
-    kudu_util
-    ${KUDU_TEST_LINK_LIBS})
+    ${KUDU_MIN_TEST_LIBS}
+    kudu_util)
 endif()
 
 # Tests
-set(KUDU_TEST_LINK_LIBS tpch ${KUDU_TEST_LINK_LIBS})
+SET_KUDU_TEST_LINK_LIBS(tpch)
 ADD_KUDU_TEST(tpch/rpc_line_item_dao-test)

http://git-wip-us.apache.org/repos/asf/kudu/blob/a8d088e1/src/kudu/cfile/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/kudu/cfile/CMakeLists.txt b/src/kudu/cfile/CMakeLists.txt
index 7eac936..14887e1 100644
--- a/src/kudu/cfile/CMakeLists.txt
+++ b/src/kudu/cfile/CMakeLists.txt
@@ -55,7 +55,7 @@ target_link_libraries(cfile
   bitshuffle)
 
 # Tests
-set(KUDU_TEST_LINK_LIBS cfile ${KUDU_MIN_TEST_LIBS})
+SET_KUDU_TEST_LINK_LIBS(cfile)
 ADD_KUDU_TEST(index-test)
 ADD_KUDU_TEST(cfile-test NUM_SHARDS 4)
 ADD_KUDU_TEST(encoding-test LABELS no_tsan)

http://git-wip-us.apache.org/repos/asf/kudu/blob/a8d088e1/src/kudu/client/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/kudu/client/CMakeLists.txt b/src/kudu/client/CMakeLists.txt
index 2e6ab1c..b800a9d 100644
--- a/src/kudu/client/CMakeLists.txt
+++ b/src/kudu/client/CMakeLists.txt
@@ -256,11 +256,11 @@ endif()
 if(NOT "${KUDU_USE_ASAN}" AND NOT "${KUDU_USE_TSAN}")
   ADD_KUDU_TEST(client_examples-test.sh RUN_SERIAL true LABELS no_dist_test)
 endif()
-set(KUDU_TEST_LINK_LIBS
+
+SET_KUDU_TEST_LINK_LIBS(
   itest_util
   kudu_client
-  mini_cluster
-  ${KUDU_MIN_TEST_LIBS})
+  mini_cluster)
 ADD_KUDU_TEST(client-test NUM_SHARDS 8 PROCESSORS 2)
 ADD_KUDU_TEST(client-unittest)
 ADD_KUDU_TEST(predicate-test)

http://git-wip-us.apache.org/repos/asf/kudu/blob/a8d088e1/src/kudu/clock/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/kudu/clock/CMakeLists.txt b/src/kudu/clock/CMakeLists.txt
index 7371aeb..e95a16f 100644
--- a/src/kudu/clock/CMakeLists.txt
+++ b/src/kudu/clock/CMakeLists.txt
@@ -31,7 +31,6 @@ target_link_libraries(clock
   kudu_common
   kudu_util)
 
-set(KUDU_TEST_LINK_LIBS ${KUDU_MIN_TEST_LIBS}
-  clock)
+SET_KUDU_TEST_LINK_LIBS(clock)
 ADD_KUDU_TEST(hybrid_clock-test PROCESSORS 3)
 ADD_KUDU_TEST(logical_clock-test)

http://git-wip-us.apache.org/repos/asf/kudu/blob/a8d088e1/src/kudu/codegen/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/kudu/codegen/CMakeLists.txt b/src/kudu/codegen/CMakeLists.txt
index c8bbbb0..74ed9a4 100644
--- a/src/kudu/codegen/CMakeLists.txt
+++ b/src/kudu/codegen/CMakeLists.txt
@@ -190,6 +190,6 @@ target_link_libraries(codegen
 # Unit tests
 #######################################
 
-set(KUDU_TEST_LINK_LIBS codegen ${KUDU_MIN_TEST_LIBS})
+SET_KUDU_TEST_LINK_LIBS(codegen)
 
 ADD_KUDU_TEST(codegen-test)

http://git-wip-us.apache.org/repos/asf/kudu/blob/a8d088e1/src/kudu/common/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/kudu/common/CMakeLists.txt b/src/kudu/common/CMakeLists.txt
index 3e3b4ee..429a2b1 100644
--- a/src/kudu/common/CMakeLists.txt
+++ b/src/kudu/common/CMakeLists.txt
@@ -76,7 +76,7 @@ ADD_EXPORTABLE_LIBRARY(kudu_common
   SRCS ${COMMON_SRCS}
   DEPS ${COMMON_LIBS})
 
-set(KUDU_TEST_LINK_LIBS kudu_common ${KUDU_MIN_TEST_LIBS})
+SET_KUDU_TEST_LINK_LIBS(kudu_common)
 ADD_KUDU_TEST(column_predicate-test)
 ADD_KUDU_TEST(encoded_key-test)
 ADD_KUDU_TEST(generic_iterators-test)

http://git-wip-us.apache.org/repos/asf/kudu/blob/a8d088e1/src/kudu/consensus/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/kudu/consensus/CMakeLists.txt b/src/kudu/consensus/CMakeLists.txt
index ca21394..f506107 100644
--- a/src/kudu/consensus/CMakeLists.txt
+++ b/src/kudu/consensus/CMakeLists.txt
@@ -117,15 +117,13 @@ target_link_libraries(consensus
   log
   protobuf)
 
-set(KUDU_TEST_LINK_LIBS
+SET_KUDU_TEST_LINK_LIBS(
   log
   consensus
   tserver_proto
   cfile
   tablet
-  kudu_util
-  ${KUDU_MIN_TEST_LIBS}
-)
+  kudu_util)
 
 ADD_KUDU_TEST(consensus_meta-test)
 ADD_KUDU_TEST(consensus_meta_manager-stress-test RUN_SERIAL true)

http://git-wip-us.apache.org/repos/asf/kudu/blob/a8d088e1/src/kudu/experiments/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/kudu/experiments/CMakeLists.txt b/src/kudu/experiments/CMakeLists.txt
index bbed26e..7bd8718 100644
--- a/src/kudu/experiments/CMakeLists.txt
+++ b/src/kudu/experiments/CMakeLists.txt
@@ -24,11 +24,11 @@ endif()
 if(NOT APPLE)
   add_executable(rwlock-perf rwlock-perf.cc)
   target_link_libraries(rwlock-perf
-    kudu_util
-    ${KUDU_MIN_TEST_LIBS})
+    ${KUDU_MIN_TEST_LIBS}
+    kudu_util)
 endif()
 
 add_executable(merge-test merge-test.cc)
 target_link_libraries(merge-test
-  kudu_util
-  ${KUDU_MIN_TEST_LIBS})
+  ${KUDU_MIN_TEST_LIBS}
+  kudu_util)

http://git-wip-us.apache.org/repos/asf/kudu/blob/a8d088e1/src/kudu/fs/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/kudu/fs/CMakeLists.txt b/src/kudu/fs/CMakeLists.txt
index b4dda2b..593a08e 100644
--- a/src/kudu/fs/CMakeLists.txt
+++ b/src/kudu/fs/CMakeLists.txt
@@ -52,7 +52,7 @@ target_link_libraries(kudu_fs_test_util
   gutil)
 
 # Tests
-set(KUDU_TEST_LINK_LIBS kudu_fs kudu_fs_test_util ${KUDU_MIN_TEST_LIBS})
+SET_KUDU_TEST_LINK_LIBS(kudu_fs kudu_fs_test_util)
 ADD_KUDU_TEST(block_manager-test)
 ADD_KUDU_TEST(block_manager_util-test)
 ADD_KUDU_TEST(block_manager-stress-test RUN_SERIAL true)

http://git-wip-us.apache.org/repos/asf/kudu/blob/a8d088e1/src/kudu/hms/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/kudu/hms/CMakeLists.txt b/src/kudu/hms/CMakeLists.txt
index fbc4c6e..432a2c7 100644
--- a/src/kudu/hms/CMakeLists.txt
+++ b/src/kudu/hms/CMakeLists.txt
@@ -74,11 +74,10 @@ add_dependencies(mini_hms hms-plugin)
 
 # Tests
 if (NOT NO_TESTS)
-  set(KUDU_TEST_LINK_LIBS
+  SET_KUDU_TEST_LINK_LIBS(
     kudu_hms
     mini_hms
-    mini_kdc
-    ${KUDU_MIN_TEST_LIBS})
+    mini_kdc)
 
   # These tests must run serially, otherwise starting the HMS can take a very long time.
   ADD_KUDU_TEST(hms_catalog-test RUN_SERIAL true NUM_SHARDS 4)

http://git-wip-us.apache.org/repos/asf/kudu/blob/a8d088e1/src/kudu/integration-tests/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/kudu/integration-tests/CMakeLists.txt b/src/kudu/integration-tests/CMakeLists.txt
index 07bc6cf..ad814e3 100644
--- a/src/kudu/integration-tests/CMakeLists.txt
+++ b/src/kudu/integration-tests/CMakeLists.txt
@@ -51,7 +51,7 @@ add_dependencies(itest_util
   kudu-tserver)
 
 # Tests
-set(KUDU_TEST_LINK_LIBS itest_util ${KUDU_MIN_TEST_LIBS})
+SET_KUDU_TEST_LINK_LIBS(itest_util)
 ADD_KUDU_TEST(all_types-itest
   PROCESSORS 4
   NUM_SHARDS 8)

http://git-wip-us.apache.org/repos/asf/kudu/blob/a8d088e1/src/kudu/master/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/kudu/master/CMakeLists.txt b/src/kudu/master/CMakeLists.txt
index 84a7d90..41a7dfe 100644
--- a/src/kudu/master/CMakeLists.txt
+++ b/src/kudu/master/CMakeLists.txt
@@ -64,8 +64,7 @@ target_link_libraries(master
   tserver_service_proto)
 
 # Tests
-set(KUDU_TEST_LINK_LIBS
-  ${KUDU_MIN_TEST_LIBS}
+SET_KUDU_TEST_LINK_LIBS(
   kudu_client
   kudu_curl_util
   master
@@ -81,6 +80,7 @@ ADD_KUDU_TEST(sys_catalog-test RESOURCE_LOCK "master-web-port")
 # Actual master executable
 add_executable(kudu-master master_main.cc)
 target_link_libraries(kudu-master
+  ${SANITIZER_OPTIONS_OVERRIDE}
   ${KRB5_REALM_OVERRIDE}
   master
   ${KUDU_BASE_LIBS})

http://git-wip-us.apache.org/repos/asf/kudu/blob/a8d088e1/src/kudu/mini-cluster/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/kudu/mini-cluster/CMakeLists.txt b/src/kudu/mini-cluster/CMakeLists.txt
index 356e492..78cee7c 100644
--- a/src/kudu/mini-cluster/CMakeLists.txt
+++ b/src/kudu/mini-cluster/CMakeLists.txt
@@ -48,5 +48,5 @@ add_dependencies(mini_cluster
   kudu-master)
 
 # Tests
-set(KUDU_TEST_LINK_LIBS mini_cluster kudu_hms ${KUDU_MIN_TEST_LIBS})
+SET_KUDU_TEST_LINK_LIBS(mini_cluster kudu_hms)
 ADD_KUDU_TEST(external_mini_cluster-test PROCESSORS 3)

http://git-wip-us.apache.org/repos/asf/kudu/blob/a8d088e1/src/kudu/rpc/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/kudu/rpc/CMakeLists.txt b/src/kudu/rpc/CMakeLists.txt
index f8cdb02..b747337 100644
--- a/src/kudu/rpc/CMakeLists.txt
+++ b/src/kudu/rpc/CMakeLists.txt
@@ -119,13 +119,12 @@ target_link_libraries(rtest_krpc
   rtest_diff_package_proto)
 
 # Tests
-set(KUDU_TEST_LINK_LIBS
+SET_KUDU_TEST_LINK_LIBS(
   krpc
   mini_kdc
   rpc_header_proto
   rtest_krpc
-  security_test_util
-  ${KUDU_MIN_TEST_LIBS})
+  security_test_util)
 ADD_KUDU_TEST(exactly_once_rpc-test PROCESSORS 10)
 ADD_KUDU_TEST(mt-rpc-test RUN_SERIAL true)
 ADD_KUDU_TEST(negotiation-test)

http://git-wip-us.apache.org/repos/asf/kudu/blob/a8d088e1/src/kudu/security/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/kudu/security/CMakeLists.txt b/src/kudu/security/CMakeLists.txt
index b79486e..e0aca70 100644
--- a/src/kudu/security/CMakeLists.txt
+++ b/src/kudu/security/CMakeLists.txt
@@ -125,11 +125,10 @@ if (NOT NO_TESTS)
     security)
 
   # Tests
-  set(KUDU_TEST_LINK_LIBS
+  SET_KUDU_TEST_LINK_LIBS(
     mini_kdc
     security
-    security_test_util
-    ${KUDU_MIN_TEST_LIBS})
+    security_test_util)
 
   ADD_KUDU_TEST(ca/cert_management-test)
   ADD_KUDU_TEST(cert-test)

http://git-wip-us.apache.org/repos/asf/kudu/blob/a8d088e1/src/kudu/server/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/kudu/server/CMakeLists.txt b/src/kudu/server/CMakeLists.txt
index 859fa32..aa0ce91 100644
--- a/src/kudu/server/CMakeLists.txt
+++ b/src/kudu/server/CMakeLists.txt
@@ -78,7 +78,7 @@ endif()
 # server_process tests
 #########################################
 
-set(KUDU_TEST_LINK_LIBS ${KUDU_MIN_TEST_LIBS}
+SET_KUDU_TEST_LINK_LIBS(
   kudu_curl_util
   server_process
   security_test_util)

http://git-wip-us.apache.org/repos/asf/kudu/blob/a8d088e1/src/kudu/tablet/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/kudu/tablet/CMakeLists.txt b/src/kudu/tablet/CMakeLists.txt
index 5f9b851..7c22c62 100644
--- a/src/kudu/tablet/CMakeLists.txt
+++ b/src/kudu/tablet/CMakeLists.txt
@@ -84,7 +84,7 @@ target_link_libraries(tablet
   kudu_util
   consensus)
 
-set(KUDU_TEST_LINK_LIBS tablet ${KUDU_MIN_TEST_LIBS})
+SET_KUDU_TEST_LINK_LIBS(tablet)
 ADD_KUDU_TEST(all_types-scan-correctness-test NUM_SHARDS 8 PROCESSORS 2)
 ADD_KUDU_TEST(cfile_set-test)
 ADD_KUDU_TEST(compaction-test)
@@ -117,5 +117,5 @@ ADD_KUDU_TEST(tablet_throttle-test)
 ADD_KUDU_TEST(transactions/transaction_tracker-test)
 
 # Some tests don't have dependencies on other tablet stuff
-set(KUDU_TEST_LINK_LIBS kudu_util gutil ${KUDU_MIN_TEST_LIBS})
+SET_KUDU_TEST_LINK_LIBS(kudu_util gutil)
 ADD_KUDU_TEST(cbtree-test RUN_SERIAL true)

http://git-wip-us.apache.org/repos/asf/kudu/blob/a8d088e1/src/kudu/tools/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/kudu/tools/CMakeLists.txt b/src/kudu/tools/CMakeLists.txt
index 3f6020f..8b36461 100644
--- a/src/kudu/tools/CMakeLists.txt
+++ b/src/kudu/tools/CMakeLists.txt
@@ -117,6 +117,7 @@ add_executable(kudu
   tool_main.cc
 )
 target_link_libraries(kudu
+  ${SANITIZER_OPTIONS_OVERRIDE}
   ${KRB5_REALM_OVERRIDE}
   clock
   consensus
@@ -153,15 +154,14 @@ target_link_libraries(kudu_tools_test_util
 # Unit tests
 #######################################
 
-set(KUDU_TEST_LINK_LIBS
+SET_KUDU_TEST_LINK_LIBS(
   itest_util
   ksck
   kudu_hms
   kudu_tools_rebalance
   kudu_tools_test_util
   kudu_tools_util
-  mini_cluster
-  ${KUDU_MIN_TEST_LIBS})
+  mini_cluster)
 ADD_KUDU_TEST(diagnostics_log_parser-test)
 ADD_KUDU_TEST(ksck-test)
 ADD_KUDU_TEST(ksck_remote-test PROCESSORS 3)

http://git-wip-us.apache.org/repos/asf/kudu/blob/a8d088e1/src/kudu/tserver/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/kudu/tserver/CMakeLists.txt b/src/kudu/tserver/CMakeLists.txt
index c411e92..7304d72 100644
--- a/src/kudu/tserver/CMakeLists.txt
+++ b/src/kudu/tserver/CMakeLists.txt
@@ -142,6 +142,7 @@ target_link_libraries(tserver
 
 add_executable(kudu-tserver tablet_server_main.cc)
 target_link_libraries(kudu-tserver
+  ${SANITIZER_OPTIONS_OVERRIDE}
   ${KRB5_REALM_OVERRIDE}
   tserver
   ${KUDU_BASE_LIBS})
@@ -158,19 +159,18 @@ if (NOT NO_TESTS)
 
   add_library(tserver_test_util ${TSERVER_TEST_UTIL_SRCS})
   target_link_libraries(tserver_test_util
-    tserver
-    ${KUDU_MIN_TEST_LIBS})
+    ${KUDU_MIN_TEST_LIBS}
+    tserver)
 endif()
 
 #########################################
 # tserver tests
 #########################################
 
-set(KUDU_TEST_LINK_LIBS
+SET_KUDU_TEST_LINK_LIBS(
   kudu_curl_util
   tserver
-  tserver_test_util
-  ${KUDU_MIN_TEST_LIBS})
+  tserver_test_util)
 ADD_KUDU_TEST(mini_tablet_server-test)
 ADD_KUDU_TEST(tablet_copy_client-test)
 ADD_KUDU_TEST(tablet_copy_source_session-test)

http://git-wip-us.apache.org/repos/asf/kudu/blob/a8d088e1/src/kudu/util/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/src/kudu/util/CMakeLists.txt b/src/kudu/util/CMakeLists.txt
index 94dd2fa..105b7ff 100644
--- a/src/kudu/util/CMakeLists.txt
+++ b/src/kudu/util/CMakeLists.txt
@@ -272,6 +272,29 @@ ADD_EXPORTABLE_LIBRARY(kudu_util_compression
   SRCS ${UTIL_COMPRESSION_SRCS}
   DEPS ${UTIL_COMPRESSION_LIBS})
 
+# See the comment in sanitizer_options.cc for details on this library's usage.
+# The top-level CMakeLists sets a ${SANITIZER_OPTIONS_OVERRIDE} variable which
+# should be linked first into all Kudu binaries.
+
+#######################################
+# sanitizer_options
+#######################################
+add_library(sanitizer_options STATIC sanitizer_options.cc)
+target_link_libraries(sanitizer_options gutil)
+if ("${KUDU_USE_ASAN}" OR "${KUDU_USE_TSAN}" OR "${KUDU_USE_UBSAN}")
+  # By default the sanitizers use addr2line utility to symbolize reports.
+  # llvm-symbolizer is faster, consumes less memory and produces much better reports.
+  # We set KUDU_EXTERNAL_SYMBOLIZER_PATH which is used in sanitizer_options.cc
+  # to set the default external_symbolizer_path.
+  SET(KUDU_LLVM_SYMBOLIZER_PATH ${THIRDPARTY_INSTALL_UNINSTRUMENTED_DIR}/bin/llvm-symbolizer)
+  if (EXISTS ${KUDU_LLVM_SYMBOLIZER_PATH})
+    target_compile_definitions(sanitizer_options PRIVATE KUDU_EXTERNAL_SYMBOLIZER_PATH=${KUDU_LLVM_SYMBOLIZER_PATH})
+  else()
+    message(SEND_ERROR
+      "Could not find llvm-symbolizer required for sanitizer builds at ${KUDU_LLVM_SYMBOLIZER_PATH}")
+  endif()
+endif()
+
 #######################################
 # kudu_test_util
 #######################################
@@ -335,7 +358,7 @@ target_link_libraries(protoc-gen-insertions gutil protobuf protoc ${KUDU_BASE_LI
 # Unit tests
 #######################################
 
-set(KUDU_TEST_LINK_LIBS kudu_util gutil ${KUDU_MIN_TEST_LIBS})
+SET_KUDU_TEST_LINK_LIBS(kudu_util gutil)
 ADD_KUDU_TEST(async_util-test)
 ADD_KUDU_TEST(atomic-test)
 ADD_KUDU_TEST(bit-util-test)

http://git-wip-us.apache.org/repos/asf/kudu/blob/a8d088e1/src/kudu/util/sanitizer_options.cc
----------------------------------------------------------------------
diff --git a/src/kudu/util/sanitizer_options.cc b/src/kudu/util/sanitizer_options.cc
new file mode 100644
index 0000000..bb0378c
--- /dev/null
+++ b/src/kudu/util/sanitizer_options.cc
@@ -0,0 +1,205 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+#include "kudu/gutil/macros.h"
+
+// Functions returning default options are declared weak in the 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 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))
+
+#if defined(ADDRESS_SANITIZER)
+SANITIZER_HOOK_ATTRIBUTE const char *__asan_default_options() {
+  return
+#if defined(KUDU_EXTERNAL_SYMBOLIZER_PATH)
+  // Overried the symbolizer used when generating reports.
+  "external_symbolizer_path=" AS_STRING(KUDU_EXTERNAL_SYMBOLIZER_PATH) " "
+#endif
+  // Prefixes up to and including this substring will be stripped from source
+  // file paths in symbolized reports.
+  "strip_path_prefix=/../ ";
+}
+#endif  // ADDRESS_SANITIZER
+
+#if defined(THREAD_SANITIZER)
+SANITIZER_HOOK_ATTRIBUTE const char *__tsan_default_options() {
+  return
+#if defined(KUDU_EXTERNAL_SYMBOLIZER_PATH)
+  // Overried the symbolizer used when generating reports.
+  "external_symbolizer_path=" AS_STRING(KUDU_EXTERNAL_SYMBOLIZER_PATH) " "
+#endif
+  // Flush TSAN memory every 10 seconds
+  // this prevents RSS blowup in unit tests which can cause tests to get
+  // killed by the OOM killer.
+  "flush_memory_ms=10000 "
+
+  // make the history buffer proportional to 2^7 (the maximum value) to
+  // keep more stack traces.
+  "history_size=7 "
+
+  // Prefixes up to and including this substring will be stripped from source
+  // file paths in symbolized reports.
+  "strip_path_prefix=/../ ";
+}
+
+SANITIZER_HOOK_ATTRIBUTE const char *__tsan_default_suppressions() {
+  return
+  // libunwind uses some double-checked locking which isn't perfectly safe.
+  // Reported at http://savannah.nongnu.org/bugs/index.php?42677
+  //
+  // With TSAN in clang 3.5, it's the init() function that's flagged as a data
+  // race (not local_addr_space_init()), due to the former calling sigfillset()
+  // on an unprotected global variable. Although init() calls local_addr_space_init(),
+  // it can sometimes be eliminated from the call stack by inlining or a tail-call
+  // # optimization, so adding the suppression on both is necessary.
+  "race:_ULx86_64_init\n"
+  "race:_ULx86_64_local_addr_space_init\n"
+
+  // TODO(todd) After upgrading to clang 6.0, libunwind's cache is getting
+  // flagged as unsafe.
+  "race:_ULx86_64_step\n"
+
+  // libev uses some lock-free synchronization, but doesn't have TSAN annotations.
+  "race:epoll_ctl\n"
+
+  // TSAN complains about data races on the global signals variable in
+  // ev_feed_signal and spoiled errno in ev_sighandler. Both are probably noise.
+  "race:ev_sighandler\n"
+
+  // See https://github.com/google/glog/issues/80 for a general list of TSAN
+  // issues in glog.
+  // 1. glog's fatal signal handler isn't signal-safe -- it allocates memory.
+  //    This isn't great, but nothing we can do about it. See
+  //    https://code.google.com/p/google-glog/issues/detail?id=191
+  // 2. LOG(FATAL) from multiple threads can also end up triggering a TSAN error.
+  // 3. g_now_entering in stacktrace_libunwind-inl.h is reset to false without
+  //    a Release_Store.
+  // 4. glog's ANNOTATE_BENIGN_RACE macro doesn't do anything.
+  // 5. Mutex::is_safe_ is accessed in an unsafe way.
+  // 6. vlocal__ is access in an unsafe way at every VLOG() or VLOG_IS_ON()
+  //    call-site.
+  "signal:logging_fail\n"
+  "race:google::LogMessage::Init\n"
+  "race:google::GetStackTrace\n"
+  "race:google::InitVLOG3__\n"
+  "race:glog_internal_namespace_::Mutex\n"
+  "race:vlocal__\n"
+
+  // gflags variables are accessed without synchronization, but FlagSaver and other
+  // APIs acquire locks when accessing them. This should be safe on x86 for
+  // primitive flag types, but not for string flags, which is why fLS is omitted.
+  "race:fLB::\n"
+  "race:fLD::\n"
+  "race:fLI::\n"
+  "race:fLI64::\n"
+  "race:fLU64::\n"
+
+  // This method in Boost's UUID library operates on static state with impunity,
+  // triggering (harmless) data races in TSAN when boost::uuids::random_generator
+  // instances are created across threads (see kudu::ObjectIdGenerator).
+  "race:boost::uuids::detail::seed_rng::sha1_random_digest_\n"
+
+  // Squeasel uses ctx->stop_flag to synchronize stopping. It always sets it with
+  // the context lock held, but sometimes reads it without the context lock. This
+  // should be safe on x86, but is nonetheless flagged by TSAN.
+  "race:sq_stop\n"
+
+  // Squeasel reads and frees ctx->listening_sockets without taking any locks. This
+  // may be an unsafe race.
+  "race:close_all_listening_sockets\n"
+
+  // ------------------------------------------------------------
+  // Known bugs below. As these JIRAs are resolved, please remove the relevant
+  // suppression.
+  // ------------------------------------------------------------
+
+  // KUDU-1283: TSAN warning from consensus OpId
+  "race:kudu::consensus::OpId::CopyFrom\n"
+
+  // KUDU-186: sketchy synchronization in catalog manager
+  "race:kudu::master::CatalogManager::Shutdown\n"
+  "race:kudu::master::CatalogManagerBgTasks::Shutdown\n"
+  "race:kudu::master::CatalogManager::~CatalogManager\n"
+
+  // KUDU-574: raft_consensus_quorum-test race on LocalTestPeerProxy destruction
+  "race:kudu::consensus::LocalTestPeerProxy::~LocalTestPeerProxy\n"
+
+  // KUDU-569: unsynchronized access to 'state_', 'acceptor_pools_', in
+  // GetBoundAddresses()
+  "race:kudu::Webserver::GetBoundAddresses\n"
+  "race:kudu::RpcServer::GetBoundAddresses\n"
+
+  // KUDU-2439: OpenSSL 1.1's atexit() handler may destroy global state while a
+  // Messenger is shutting down and still accessing that state. See
+  // https://github.com/openssl/openssl/issues/6214 for more details.
+  //
+  // This is carried out by OPENSSL_cleanup, but TSAN's unwinder doesn't
+  // include any stack frame above the libcrypto lock destruction or memory release
+  // call for some reason, so we have to do something more generic.
+  "called_from_lib:libcrypto.so\n";
+}
+#endif  // THREAD_SANITIZER
+
+#if defined(LEAK_SANITIZER)
+SANITIZER_HOOK_ATTRIBUTE const char *__lsan_default_options() {
+  return
+#if defined(KUDU_EXTERNAL_SYMBOLIZER_PATH)
+  // Overried the symbolizer used when generating reports.
+  "external_symbolizer_path=" AS_STRING(KUDU_EXTERNAL_SYMBOLIZER_PATH) " "
+#endif
+  // Prefixes up to and including this substring will be stripped from source
+  // file paths in symbolized reports.
+  "strip_path_prefix=/../ ";
+}
+
+SANITIZER_HOOK_ATTRIBUTE const char *__lsan_default_suppressions() {
+  return
+  // False positive from atexit() registration in libc
+  "leak:*__new_exitfn*\n"
+
+  // False positive from krb5 < 1.12
+  // Fixed by upstream commit 379d39c17b8930718e98185a5b32a0f7f3e3b4b6
+  "leak:krb5_authdata_import_attributes\n";
+}
+#endif  // LEAK_SANITIZER
+
+#if defined(UNDEFINED_SANITIZER)
+SANITIZER_HOOK_ATTRIBUTE const char* __ubsan_default_options() {
+  return
+#if defined(KUDU_EXTERNAL_SYMBOLIZER_PATH)
+  // Overried the symbolizer used when generating reports.
+  "external_symbolizer_path=" AS_STRING(KUDU_EXTERNAL_SYMBOLIZER_PATH) " "
+#endif
+  // Print the stacktrace when UBSan reports an error.
+  "print_stacktrace=1 "
+  // Prefixes up to and including this substring will be stripped from source
+  // file paths in symbolized reports.
+  "strip_path_prefix=/../ ";
+}
+#endif  // UNDEFINED_SANITIZER