You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@impala.apache.org by jb...@apache.org on 2017/09/07 03:50:22 UTC
[4/8] incubator-impala git commit: IMPALA-5902: add ThreadSanitizer
build
IMPALA-5902: add ThreadSanitizer build
This is sufficient to get Impala to come up and run queries with
thread sanitizer enabled.
I have not triaged or fixed the data races that are reported, that
is left for follow-on work.
Change-Id: I22f8faeefa5e157279c5973fe28bc573b7606d50
Reviewed-on: http://gerrit.cloudera.org:8080/7977
Reviewed-by: Tim Armstrong <ta...@cloudera.com>
Tested-by: Impala Public Jenkins
Project: http://git-wip-us.apache.org/repos/asf/incubator-impala/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-impala/commit/b1edaf21
Tree: http://git-wip-us.apache.org/repos/asf/incubator-impala/tree/b1edaf21
Diff: http://git-wip-us.apache.org/repos/asf/incubator-impala/diff/b1edaf21
Branch: refs/heads/master
Commit: b1edaf215e537d8cef5ffb305973b6c5baa63583
Parents: be98aaa
Author: Tim Armstrong <ta...@cloudera.com>
Authored: Thu Aug 31 23:18:20 2017 -0700
Committer: Impala Public Jenkins <im...@gerrit.cloudera.org>
Committed: Thu Sep 7 01:22:41 2017 +0000
----------------------------------------------------------------------
CMakeLists.txt | 3 ++-
be/CMakeLists.txt | 16 ++++++++++---
be/src/common/init.cc | 18 +++++++-------
be/src/gutil/atomicops-internals-tsan.h | 18 ++++++++++++++
be/src/runtime/bufferpool/system-allocator.cc | 2 +-
be/src/runtime/exec-env.cc | 2 +-
be/src/runtime/query-exec-mgr.cc | 4 ++--
be/src/util/default-path-handlers.cc | 6 ++---
be/src/util/memory-metrics.cc | 10 ++++----
be/src/util/memory-metrics.h | 16 ++++++-------
be/src/util/metrics-test.cc | 2 +-
be/src/util/pprof-path-handlers.cc | 12 +++++-----
bin/make_impala.sh | 3 ++-
bin/run-backend-tests.sh | 1 +
bin/start-catalogd.sh | 1 +
bin/start-impalad.sh | 1 +
bin/start-statestored.sh | 1 +
buildall.sh | 7 ++++++
common/thrift/metrics.json | 6 ++---
tests/common/environ.py | 28 +++++++++++++++-------
20 files changed, 105 insertions(+), 52 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/b1edaf21/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e5c2fdb..e8a2355 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -209,7 +209,8 @@ find_package(LlvmBinaries REQUIRED)
if ("${CMAKE_BUILD_TYPE}" STREQUAL "DEBUG"
OR "${CMAKE_BUILD_TYPE}" STREQUAL "ADDRESS_SANITIZER"
OR "${CMAKE_BUILD_TYPE}" STREQUAL "TIDY"
- OR "${CMAKE_BUILD_TYPE}" STREQUAL "UBSAN")
+ OR "${CMAKE_BUILD_TYPE}" STREQUAL "UBSAN"
+ OR "${CMAKE_BUILD_TYPE}" STREQUAL "TSAN")
# Use the LLVM libaries with assertions for debug builds.
set(LLVM_ROOT ${LLVM_DEBUG_ROOT})
endif()
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/b1edaf21/be/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/be/CMakeLists.txt b/be/CMakeLists.txt
index 5b0d89d..bf7aa26 100644
--- a/be/CMakeLists.txt
+++ b/be/CMakeLists.txt
@@ -110,6 +110,11 @@ SET(CXX_FLAGS_UBSAN "${CXX_FLAGS_UBSAN} -fno-wrapv")
# To ease debugging, turn off all optimizations:
SET(CXX_FLAGS_UBSAN "${CXX_FLAGS_UBSAN} -O0")
+# Set the flags to the thread sanitizer, also known as "tsan"
+# Turn on sanitizer and debug symbols to get stack traces:
+SET(CXX_FLAGS_TSAN "${CXX_CLANG_FLAGS} -O1 -ggdb3 -fno-omit-frame-pointer")
+SET(CXX_FLAGS_TSAN "${CXX_FLAGS_TSAN} -fsanitize=thread -DTHREAD_SANITIZER")
+
SET(CXX_FLAGS_TIDY "${CXX_CLANG_FLAGS}")
# Catching unused variables requires an optimization level greater than 0
SET(CXX_FLAGS_TIDY "${CXX_FLAGS_TIDY} -O1")
@@ -136,6 +141,8 @@ elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "TIDY")
SET(CMAKE_CXX_FLAGS "${CXX_FLAGS_TIDY}")
elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "UBSAN")
SET(CMAKE_CXX_FLAGS "${CXX_FLAGS_UBSAN}")
+elseif ("${CMAKE_BUILD_TYPE}" STREQUAL "TSAN")
+ SET(CMAKE_CXX_FLAGS "${CXX_FLAGS_TSAN}")
else()
message(FATAL_ERROR "Unknown build type: ${CMAKE_BUILD_TYPE}")
endif()
@@ -159,7 +166,8 @@ if (CCACHE AND NOT DEFINED ENV{DISABLE_CCACHE})
set(RULE_LAUNCH_PREFIX ccache)
if ("${CMAKE_BUILD_TYPE}" STREQUAL "ADDRESS_SANITIZER"
OR "${CMAKE_BUILD_TYPE}" STREQUAL "TIDY"
- OR "${CMAKE_BUILD_TYPE}" STREQUAL "UBSAN")
+ OR "${CMAKE_BUILD_TYPE}" STREQUAL "UBSAN"
+ OR "${CMAKE_BUILD_TYPE}" STREQUAL "TSAN")
# Need to set CCACHE_CPP so that ccache calls clang with the original source file for
# both preprocessing and compilation. Otherwise, ccache will use clang to preprocess
# the file and then call clang with the preprocessed output if not cached. However,
@@ -294,7 +302,8 @@ add_definitions(-fPIC)
# set compile output directory
if ("${CMAKE_BUILD_TYPE}" STREQUAL "DEBUG" OR
"${CMAKE_BUILD_TYPE}" STREQUAL "ADDRESS_SANITIZER" OR
- "${CMAKE_BUILD_TYPE}" STREQUAL "UBSAN")
+ "${CMAKE_BUILD_TYPE}" STREQUAL "UBSAN" OR
+ "${CMAKE_BUILD_TYPE}" STREQUAL "TSAN")
set(BUILD_OUTPUT_ROOT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/build/debug/")
else()
set(BUILD_OUTPUT_ROOT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/build/release/")
@@ -436,7 +445,8 @@ set (IMPALA_LINK_LIBS ${IMPALA_LINK_LIBS}
# sanitizer build. Address sanitizer is incompatible with tcmalloc (they both intercept
# malloc/free)
set (IMPALA_LINK_LIBS_NO_TCMALLOC ${IMPALA_LINK_LIBS})
-if (NOT "${CMAKE_BUILD_TYPE}" STREQUAL "ADDRESS_SANITIZER")
+if (NOT "${CMAKE_BUILD_TYPE}" STREQUAL "ADDRESS_SANITIZER" AND
+ NOT "${CMAKE_BUILD_TYPE}" STREQUAL "TSAN")
set (IMPALA_LINK_LIBS ${IMPALA_LINK_LIBS} tcmallocstatic)
endif()
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/b1edaf21/be/src/common/init.cc
----------------------------------------------------------------------
diff --git a/be/src/common/init.cc b/be/src/common/init.cc
index f2df173..ce55067 100644
--- a/be/src/common/init.cc
+++ b/be/src/common/init.cc
@@ -137,17 +137,15 @@ static scoped_ptr<impala::Thread> pause_monitor;
BufferPool* buffer_pool = env->buffer_pool();
if (buffer_pool != nullptr) buffer_pool->Maintenance();
-#ifndef ADDRESS_SANITIZER
- // When using tcmalloc, the process limit as measured by our trackers will
- // be out of sync with the process usage. The metric is refreshed whenever
- // memory is consumed or released via a MemTracker, so on a system with
- // queries executing it will be refreshed frequently. However if the system
- // is idle, we need to refresh the tracker occasionally since untracked
- // memory may be allocated or freed, e.g. by background threads.
+ // The process limit as measured by our trackers may get out of sync with the
+ // process usage if memory is allocated or freed without updating a MemTracker.
+ // The metric is refreshed whenever memory is consumed or released via a MemTracker,
+ // so on a system with queries executing it will be refreshed frequently. However
+ // if the system is idle, we need to refresh the tracker occasionally since
+ // untracked memory may be allocated or freed, e.g. by background threads.
if (env->process_mem_tracker() != nullptr) {
env->process_mem_tracker()->RefreshConsumptionFromMetric();
}
-#endif
}
// Periodically refresh values of the aggregate memory metrics to ensure they are
// somewhat up-to-date.
@@ -198,7 +196,9 @@ void impala::InitCommonRuntime(int argc, char** argv, bool init_jvm,
impala::InitGoogleLoggingSafe(argv[0]);
// Breakpad needs flags and logging to initialize.
ABORT_IF_ERROR(RegisterMinidump(argv[0]));
+#ifndef THREAD_SANITIZER
AtomicOps_x86CPUFeaturesInit();
+#endif
impala::InitThreading();
impala::TimestampParser::Init();
impala::SeedOpenSSLRNG();
@@ -243,7 +243,7 @@ void impala::InitCommonRuntime(int argc, char** argv, bool init_jvm,
if (impala::KuduIsAvailable()) impala::InitKuduLogging();
-#ifndef ADDRESS_SANITIZER
+#if !defined(ADDRESS_SANITIZER) && !defined(THREAD_SANITIZER)
// tcmalloc and address sanitizer can not be used together
if (FLAGS_enable_process_lifetime_heap_profiling) {
HeapProfilerStart(FLAGS_heap_profile_dir.c_str());
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/b1edaf21/be/src/gutil/atomicops-internals-tsan.h
----------------------------------------------------------------------
diff --git a/be/src/gutil/atomicops-internals-tsan.h b/be/src/gutil/atomicops-internals-tsan.h
index aecaefc..a1fa71b 100644
--- a/be/src/gutil/atomicops-internals-tsan.h
+++ b/be/src/gutil/atomicops-internals-tsan.h
@@ -202,6 +202,24 @@ inline Atomic64 Release_CompareAndSwap(volatile Atomic64 *ptr,
return cmp;
}
+inline Atomic32 Barrier_CompareAndSwap(volatile Atomic32 *ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ Atomic32 cmp = old_value;
+ __tsan_atomic32_compare_exchange_strong(ptr, &cmp, new_value,
+ __tsan_memory_order_acq_rel, __tsan_memory_order_relaxed);
+ return cmp;
+}
+
+inline Atomic64 Barrier_CompareAndSwap(volatile Atomic64 *ptr,
+ Atomic64 old_value,
+ Atomic64 new_value) {
+ Atomic64 cmp = old_value;
+ __tsan_atomic64_compare_exchange_strong(ptr, &cmp, new_value,
+ __tsan_memory_order_acq_rel, __tsan_memory_order_relaxed);
+ return cmp;
+}
+
inline void MemoryBarrier() {
__tsan_atomic_thread_fence(__tsan_memory_order_seq_cst);
}
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/b1edaf21/be/src/runtime/bufferpool/system-allocator.cc
----------------------------------------------------------------------
diff --git a/be/src/runtime/bufferpool/system-allocator.cc b/be/src/runtime/bufferpool/system-allocator.cc
index 8bbce70..b3ba2b8 100644
--- a/be/src/runtime/bufferpool/system-allocator.cc
+++ b/be/src/runtime/bufferpool/system-allocator.cc
@@ -46,7 +46,7 @@ static int64_t HUGE_PAGE_SIZE = 2LL * 1024 * 1024;
SystemAllocator::SystemAllocator(int64_t min_buffer_len)
: min_buffer_len_(min_buffer_len) {
DCHECK(BitUtil::IsPowerOf2(min_buffer_len));
-#ifndef ADDRESS_SANITIZER
+#if !defined(ADDRESS_SANITIZER) && !defined(THREAD_SANITIZER)
// Free() assumes that aggressive decommit is enabled for TCMalloc.
size_t aggressive_decommit_enabled;
MallocExtension::instance()->GetNumericProperty(
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/b1edaf21/be/src/runtime/exec-env.cc
----------------------------------------------------------------------
diff --git a/be/src/runtime/exec-env.cc b/be/src/runtime/exec-env.cc
index 2907768..fe4825d 100644
--- a/be/src/runtime/exec-env.cc
+++ b/be/src/runtime/exec-env.cc
@@ -294,7 +294,7 @@ Status ExecEnv::StartServices() {
BufferPoolMetric::UNUSED_RESERVATION_BYTES));
obj_pool_->Add(new MemTracker(negated_unused_reservation, -1,
"Buffer Pool: Unused Reservation", mem_tracker_.get()));
-#ifndef ADDRESS_SANITIZER
+#if !defined(ADDRESS_SANITIZER) && !defined(THREAD_SANITIZER)
// Aggressive decommit is required so that unused pages in the TCMalloc page heap are
// not backed by physical pages and do not contribute towards memory consumption.
size_t aggressive_decommit_enabled = 0;
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/b1edaf21/be/src/runtime/query-exec-mgr.cc
----------------------------------------------------------------------
diff --git a/be/src/runtime/query-exec-mgr.cc b/be/src/runtime/query-exec-mgr.cc
index 22c2826..901ddbd 100644
--- a/be/src/runtime/query-exec-mgr.cc
+++ b/be/src/runtime/query-exec-mgr.cc
@@ -111,8 +111,8 @@ QueryState* QueryExecMgr::GetOrCreateQueryState(
void QueryExecMgr::StartQueryHelper(QueryState* qs) {
qs->StartFInstances();
-#ifndef ADDRESS_SANITIZER
- // tcmalloc and address sanitizer cannot be used together
+#if !defined(ADDRESS_SANITIZER) && !defined(THREAD_SANITIZER)
+ // tcmalloc and address or thread sanitizer cannot be used together
if (FLAGS_log_mem_usage_interval > 0) {
uint64_t num_complete = ImpaladMetrics::IMPALA_SERVER_NUM_FRAGMENTS->value();
if (num_complete % FLAGS_log_mem_usage_interval == 0) {
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/b1edaf21/be/src/util/default-path-handlers.cc
----------------------------------------------------------------------
diff --git a/be/src/util/default-path-handlers.cc b/be/src/util/default-path-handlers.cc
index 9334316..88d23f1 100644
--- a/be/src/util/default-path-handlers.cc
+++ b/be/src/util/default-path-handlers.cc
@@ -135,8 +135,8 @@ void MemUsageHandler(MemTracker* mem_tracker, MetricGroup* metric_group,
document->AddMember("consumption", consumption, document->GetAllocator());
stringstream ss;
-#ifdef ADDRESS_SANITIZER
- ss << "Memory tracking is not available with address sanitizer builds.";
+#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER)
+ ss << "Memory tracking is not available with address or thread sanitizer builds.";
#else
char buf[2048];
MallocExtension::instance()->GetStats(buf, 2048);
@@ -238,7 +238,7 @@ void AddDefaultUrlCallbacks(
webserver->RegisterUrlCallback("/memz", "memz.tmpl", callback);
}
-#ifndef ADDRESS_SANITIZER
+#if !defined(ADDRESS_SANITIZER) && !defined(THREAD_SANITIZER)
// Remote (on-demand) profiling is disabled if the process is already being profiled.
if (!FLAGS_enable_process_lifetime_heap_profiling) {
AddPprofUrlCallbacks(webserver);
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/b1edaf21/be/src/util/memory-metrics.cc
----------------------------------------------------------------------
diff --git a/be/src/util/memory-metrics.cc b/be/src/util/memory-metrics.cc
index 7c41bdf..d1e7a16 100644
--- a/be/src/util/memory-metrics.cc
+++ b/be/src/util/memory-metrics.cc
@@ -47,7 +47,7 @@ TcmallocMetric* TcmallocMetric::TOTAL_BYTES_RESERVED = nullptr;
TcmallocMetric* TcmallocMetric::PAGEHEAP_UNMAPPED_BYTES = nullptr;
TcmallocMetric::PhysicalBytesMetric* TcmallocMetric::PHYSICAL_BYTES_RESERVED = nullptr;
-AsanMallocMetric* AsanMallocMetric::BYTES_ALLOCATED = nullptr;
+SanitizerMallocMetric* SanitizerMallocMetric::BYTES_ALLOCATED = nullptr;
BufferPoolMetric* BufferPoolMetric::LIMIT = nullptr;
BufferPoolMetric* BufferPoolMetric::SYSTEM_ALLOCATED = nullptr;
@@ -81,10 +81,10 @@ Status impala::RegisterMemoryMetrics(MetricGroup* metrics, bool register_jvm_met
used_metrics.push_back(BufferPoolMetric::SYSTEM_ALLOCATED);
}
-#ifdef ADDRESS_SANITIZER
- AsanMallocMetric::BYTES_ALLOCATED = metrics->RegisterMetric(
- new AsanMallocMetric(MetricDefs::Get("asan-total-bytes-allocated")));
- used_metrics.push_back(AsanMallocMetric::BYTES_ALLOCATED);
+#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER)
+ SanitizerMallocMetric::BYTES_ALLOCATED = metrics->RegisterMetric(
+ new SanitizerMallocMetric(MetricDefs::Get("sanitizer-total-bytes-allocated")));
+ used_metrics.push_back(SanitizerMallocMetric::BYTES_ALLOCATED);
#else
MetricGroup* tcmalloc_metrics = metrics->GetOrCreateChildGroup("tcmalloc");
// We rely on TCMalloc for our global memory metrics, so skip setting them up
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/b1edaf21/be/src/util/memory-metrics.h
----------------------------------------------------------------------
diff --git a/be/src/util/memory-metrics.h b/be/src/util/memory-metrics.h
index e1f1e4a..5491f8c 100644
--- a/be/src/util/memory-metrics.h
+++ b/be/src/util/memory-metrics.h
@@ -23,7 +23,7 @@
#include <boost/bind.hpp>
#include <boost/thread/mutex.hpp>
#include <gperftools/malloc_extension.h>
-#ifdef ADDRESS_SANITIZER
+#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER)
#include <sanitizer/allocator_interface.h>
#endif
@@ -125,7 +125,7 @@ class TcmallocMetric : public IntGauge {
: IntGauge(def, 0), tcmalloc_var_(tcmalloc_var) { }
virtual void CalculateValue() {
-#ifndef ADDRESS_SANITIZER
+#if !defined(ADDRESS_SANITIZER) && !defined(THREAD_SANITIZER)
DCHECK_EQ(sizeof(size_t), sizeof(value_));
MallocExtension::instance()->GetNumericProperty(tcmalloc_var_.c_str(),
reinterpret_cast<size_t*>(&value_));
@@ -133,15 +133,15 @@ class TcmallocMetric : public IntGauge {
}
};
-/// Alternative to TCMallocMetric if we're running under Address Sanitizer, which
-/// does not provide the same metrics.
-class AsanMallocMetric : public IntGauge {
+/// Alternative to TCMallocMetric if we're running under a sanitizer that replaces
+/// malloc(), e.g. address or thread sanitizer.
+class SanitizerMallocMetric : public IntGauge {
public:
- AsanMallocMetric(const TMetricDef& def) : IntGauge(def, 0) {}
- static AsanMallocMetric* BYTES_ALLOCATED;
+ SanitizerMallocMetric(const TMetricDef& def) : IntGauge(def, 0) {}
+ static SanitizerMallocMetric* BYTES_ALLOCATED;
private:
virtual void CalculateValue() override {
-#ifdef ADDRESS_SANITIZER
+#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER)
value_ = __sanitizer_get_current_allocated_bytes();
#endif
}
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/b1edaf21/be/src/util/metrics-test.cc
----------------------------------------------------------------------
diff --git a/be/src/util/metrics-test.cc b/be/src/util/metrics-test.cc
index 08ca266..0126281 100644
--- a/be/src/util/metrics-test.cc
+++ b/be/src/util/metrics-test.cc
@@ -215,7 +215,7 @@ TEST_F(MetricsTest, StatsMetricsSingle) {
}
TEST_F(MetricsTest, MemMetric) {
-#ifndef ADDRESS_SANITIZER
+#if !defined(ADDRESS_SANITIZER) && !defined(THREAD_SANITIZER)
MetricGroup metrics("MemMetrics");
ASSERT_OK(RegisterMemoryMetrics(&metrics, false, nullptr, nullptr));
// Smoke test to confirm that tcmalloc metrics are returning reasonable values.
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/b1edaf21/be/src/util/pprof-path-handlers.cc
----------------------------------------------------------------------
diff --git a/be/src/util/pprof-path-handlers.cc b/be/src/util/pprof-path-handlers.cc
index b8f245c..bc04b2c 100644
--- a/be/src/util/pprof-path-handlers.cc
+++ b/be/src/util/pprof-path-handlers.cc
@@ -54,9 +54,9 @@ void PprofCmdLineHandler(const Webserver::ArgumentMap& args, stringstream* outpu
// by calling HeapProfileStart(filename), continue to do work, and then, some number of
// seconds later, call GetHeapProfile() followed by HeapProfilerStop().
void PprofHeapHandler(const Webserver::ArgumentMap& args, stringstream* output) {
-#ifdef ADDRESS_SANITIZER
+#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER)
(void)PPROF_DEFAULT_SAMPLE_SECS; // Avoid unused variable warning.
- (*output) << "Heap profiling is not available with address sanitizer builds.";
+ (*output) << "Heap profiling is not available with address/thread sanitizer builds.";
#else
Webserver::ArgumentMap::const_iterator it = args.find("seconds");
int seconds = PPROF_DEFAULT_SAMPLE_SECS;
@@ -78,8 +78,8 @@ void PprofHeapHandler(const Webserver::ArgumentMap& args, stringstream* output)
// The server should respond by calling ProfilerStart(), continuing to do its work,
// and then, XX seconds later, calling ProfilerStop().
void PprofCpuProfileHandler(const Webserver::ArgumentMap& args, stringstream* output) {
-#ifdef ADDRESS_SANITIZER
- (*output) << "CPU profiling is not available with address sanitizer builds.";
+#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER)
+ (*output) << "CPU profiling is not available with address/thread sanitizer builds.";
#else
Webserver::ArgumentMap::const_iterator it = args.find("seconds");
int seconds = PPROF_DEFAULT_SAMPLE_SECS;
@@ -106,8 +106,8 @@ void PprofCpuProfileHandler(const Webserver::ArgumentMap& args, stringstream* ou
// The server should respond by calling:
// MallocExtension::instance()->GetHeapGrowthStacks(&output);
void PprofGrowthHandler(const Webserver::ArgumentMap& args, stringstream* output) {
-#ifdef ADDRESS_SANITIZER
- (*output) << "Growth profiling is not available with address sanitizer builds.";
+#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER)
+ (*output) << "Growth profiling is not available with address/thread sanitizer builds.";
#else
string heap_growth_stack;
MallocExtension::instance()->GetHeapGrowthStacks(&heap_growth_stack);
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/b1edaf21/bin/make_impala.sh
----------------------------------------------------------------------
diff --git a/bin/make_impala.sh b/bin/make_impala.sh
index 8d164c2..cf05278 100755
--- a/bin/make_impala.sh
+++ b/bin/make_impala.sh
@@ -149,7 +149,8 @@ then
if [[ ("$TARGET_BUILD_TYPE" == "ADDRESS_SANITIZER") \
|| ("$TARGET_BUILD_TYPE" == "TIDY") \
- || ("$TARGET_BUILD_TYPE" == "UBSAN") ]]
+ || ("$TARGET_BUILD_TYPE" == "UBSAN") \
+ || ("$TARGET_BUILD_TYPE" == "TSAN") ]]
then
CMAKE_ARGS+=(-DCMAKE_TOOLCHAIN_FILE=$IMPALA_HOME/cmake_modules/clang_toolchain.cmake)
else
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/b1edaf21/bin/run-backend-tests.sh
----------------------------------------------------------------------
diff --git a/bin/run-backend-tests.sh b/bin/run-backend-tests.sh
index 98630b0..d4d3142 100755
--- a/bin/run-backend-tests.sh
+++ b/bin/run-backend-tests.sh
@@ -40,5 +40,6 @@ export CTEST_OUTPUT_ON_FAILURE=1
export ASAN_OPTIONS="handle_segv=0 detect_leaks=0 allocator_may_return_null=1"
export UBSAN_OPTIONS="print_stacktrace=1"
UBSAN_OPTIONS="${UBSAN_OPTIONS} suppressions=${IMPALA_HOME}/bin/ubsan-suppressions.txt"
+export TSAN_OPTIONS="halt_on_error=1 history_size=7"
export PATH="${IMPALA_TOOLCHAIN}/llvm-${IMPALA_LLVM_VERSION}/bin:${PATH}"
"${MAKE_CMD:-make}" test ARGS="${BE_TEST_ARGS}"
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/b1edaf21/bin/start-catalogd.sh
----------------------------------------------------------------------
diff --git a/bin/start-catalogd.sh b/bin/start-catalogd.sh
index 3eeaf2e..4ec6846 100755
--- a/bin/start-catalogd.sh
+++ b/bin/start-catalogd.sh
@@ -73,5 +73,6 @@ fi
export ASAN_OPTIONS="handle_segv=0 detect_leaks=0 allocator_may_return_null=1"
export UBSAN_OPTIONS="print_stacktrace=1"
UBSAN_OPTIONS="${UBSAN_OPTIONS} suppressions=${IMPALA_HOME}/bin/ubsan-suppressions.txt"
+export TSAN_OPTIONS="halt_on_error=0 history_size=7"
export PATH="${IMPALA_TOOLCHAIN}/llvm-${IMPALA_LLVM_VERSION}/bin:${PATH}"
exec ${BINARY_BASE_DIR}/${BUILD_TYPE}/catalog/catalogd ${CATALOGD_ARGS}
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/b1edaf21/bin/start-impalad.sh
----------------------------------------------------------------------
diff --git a/bin/start-impalad.sh b/bin/start-impalad.sh
index d4602b5..76a5f2c 100755
--- a/bin/start-impalad.sh
+++ b/bin/start-impalad.sh
@@ -101,5 +101,6 @@ fi
export ASAN_OPTIONS="handle_segv=0 detect_leaks=0 allocator_may_return_null=1"
export UBSAN_OPTIONS="print_stacktrace=1"
UBSAN_OPTIONS="${UBSAN_OPTIONS} suppressions=${IMPALA_HOME}/bin/ubsan-suppressions.txt"
+export TSAN_OPTIONS="halt_on_error=0 history_size=7"
export PATH="${IMPALA_TOOLCHAIN}/llvm-${IMPALA_LLVM_VERSION}/bin:${PATH}"
exec ${TOOL_PREFIX} ${IMPALA_CMD} ${IMPALAD_ARGS}
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/b1edaf21/bin/start-statestored.sh
----------------------------------------------------------------------
diff --git a/bin/start-statestored.sh b/bin/start-statestored.sh
index 85fe221..02cf09f 100755
--- a/bin/start-statestored.sh
+++ b/bin/start-statestored.sh
@@ -62,5 +62,6 @@ fi
export ASAN_OPTIONS="handle_segv=0 detect_leaks=0 allocator_may_return_null=1"
export UBSAN_OPTIONS="print_stacktrace=1"
UBSAN_OPTIONS="${UBSAN_OPTIONS} suppressions=${IMPALA_HOME}/bin/ubsan-suppressions.txt"
+export TSAN_OPTIONS="halt_on_error=0 history_size=7"
export PATH="${IMPALA_TOOLCHAIN}/llvm-${IMPALA_LLVM_VERSION}/bin:${PATH}"
exec ${BINARY_BASE_DIR}/${BUILD_TYPE}/statestore/statestored ${STATESTORED_ARGS}
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/b1edaf21/buildall.sh
----------------------------------------------------------------------
diff --git a/buildall.sh b/buildall.sh
index bcc6ae3..d14c2ea 100755
--- a/buildall.sh
+++ b/buildall.sh
@@ -60,6 +60,7 @@ BUILD_ASAN=0
BUILD_FE_ONLY=0
BUILD_TIDY=0
BUILD_UBSAN=0
+BUILD_TSAN=0
# Export MAKE_CMD so it is visible in scripts that invoke make, e.g. copy-udfs-udas.sh
export MAKE_CMD=make
LZO_CMAKE_ARGS=
@@ -118,6 +119,9 @@ do
-ubsan)
BUILD_UBSAN=1
;;
+ -tsan)
+ BUILD_TSAN=1
+ ;;
-testpairwise)
EXPLORATION_STRATEGY=pairwise
;;
@@ -268,6 +272,9 @@ fi
if [[ ${BUILD_UBSAN} -eq 1 ]]; then
CMAKE_BUILD_TYPE=UBSAN
fi
+if [[ ${BUILD_TSAN} -eq 1 ]]; then
+ CMAKE_BUILD_TYPE=TSAN
+fi
MAKE_IMPALA_ARGS+=" -build_type=${CMAKE_BUILD_TYPE}"
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/b1edaf21/common/thrift/metrics.json
----------------------------------------------------------------------
diff --git a/common/thrift/metrics.json b/common/thrift/metrics.json
index 567e1bf..4ba94be 100644
--- a/common/thrift/metrics.json
+++ b/common/thrift/metrics.json
@@ -1114,16 +1114,16 @@
"key": "tcmalloc.total-bytes-reserved"
},
{
- "description": "Bytes allocated from Address Sanitizer's malloc (Address Sanitizer debug builds only)",
+ "description": "Bytes allocated from the sanitizer malloc (Sanitizer debug builds only)",
"contexts": [
"STATESTORE",
"CATALOGSERVER",
"IMPALAD"
],
- "label": "Address Sanitizer Malloc Bytes Allocated",
+ "label": "Sanitizer Malloc Bytes Allocated",
"units": "BYTES",
"kind": "GAUGE",
- "key": "asan-total-bytes-allocated"
+ "key": "sanitizer-total-bytes-allocated"
},
{
"description": "Maximum allowed bytes allocated by the buffer pool.",
http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/b1edaf21/tests/common/environ.py
----------------------------------------------------------------------
diff --git a/tests/common/environ.py b/tests/common/environ.py
index 571dc65..48c4cba 100644
--- a/tests/common/environ.py
+++ b/tests/common/environ.py
@@ -35,7 +35,6 @@ except ImportError as e:
LOG = logging.getLogger('tests.common.environ')
-
test_start_cluster_args = os.environ.get("TEST_START_CLUSTER_ARGS", "")
# Find the likely BuildType of the running Impala. Assume it's found through the path
@@ -58,8 +57,8 @@ IMPALAD_PATH = os.path.join(impalad_basedir, 'service', 'impalad')
class SpecificImpaladBuildTypes:
"""
- Represent a specific build type. In reality, there 5 specific build types. These
- specific build types are needed by Python test code.
+ Represent a specific build type. These specific build types are needed by Python test
+ code.
The specific build types and their *most distinguishing* compiler options are:
@@ -68,6 +67,7 @@ class SpecificImpaladBuildTypes:
3. DEBUG_CODE_COVERAGE (gcc -ggdb -ftest-coverage)
4. RELEASE (gcc)
5. RELEASE_CODE_COVERAGE (gcc -ftest-coverage)
+ 6. THREAD_SANITIZER (clang -fsanitize=thread)
"""
# ./buildall.sh -asan
ADDRESS_SANITIZER = 'address_sanitizer'
@@ -79,6 +79,8 @@ class SpecificImpaladBuildTypes:
RELEASE = 'release'
# ./buildall.sh -release -codecoverage
RELEASE_CODE_COVERAGE = 'release_code_coverage'
+ # ./buildall.sh -tsan
+ THREAD_SANITIZER = 'thread_sanitizer'
class ImpaladBuild(object):
@@ -111,6 +113,12 @@ class ImpaladBuild(object):
"""
return self.specific_build_type == SpecificImpaladBuildTypes.ADDRESS_SANITIZER
+ def is_tsan(self):
+ """
+ Return whether the Impala under test was compiled with TSAN.
+ """
+ return self.specific_build_type == SpecificImpaladBuildTypes.THREAD_SANITIZER
+
def is_dev(self):
"""
Return whether the Impala under test is a development build (i.e., any debug or ASAN
@@ -118,14 +126,15 @@ class ImpaladBuild(object):
"""
return self.specific_build_type in (
SpecificImpaladBuildTypes.ADDRESS_SANITIZER, SpecificImpaladBuildTypes.DEBUG,
- SpecificImpaladBuildTypes.DEBUG_CODE_COVERAGE)
+ SpecificImpaladBuildTypes.DEBUG_CODE_COVERAGE,
+ SpecificImpaladBuildTypes.THREAD_SANITIZER)
def runs_slowly(self):
"""
Return whether the Impala under test "runs slowly". For our purposes this means
- either compiled with code coverage enabled or ASAN.
+ either compiled with code coverage enabled, ASAN or TSAN.
"""
- return self.has_code_coverage() or self.is_asan()
+ return self.has_code_coverage() or self.is_asan() or self.is_tsan()
def _get_impalad_dwarf_info(self):
"""
@@ -170,7 +179,8 @@ class ImpaladBuild(object):
assuming a debug build and log a warning.
"""
ASAN_CU_NAME = 'asan_preinit.cc'
- NON_ASAN_CU_NAME = 'daemon-main.cc'
+ TSAN_CU_NAME = 'tsan_clock.cc'
+ DEFAULT_CU_NAME = 'daemon-main.cc'
GDB_FLAG = '-ggdb'
CODE_COVERAGE_FLAG = '-ftest-coverage'
@@ -185,7 +195,9 @@ class ImpaladBuild(object):
if die_name.endswith(ASAN_CU_NAME):
specific_build_type = SpecificImpaladBuildTypes.ADDRESS_SANITIZER
- elif not die_name.endswith(NON_ASAN_CU_NAME):
+ if die_name.endswith(TSAN_CU_NAME):
+ specific_build_type = SpecificImpaladBuildTypes.THREAD_SANITIZER
+ elif not die_name.endswith(DEFAULT_CU_NAME):
LOG.warn('Unexpected DW_AT_name in first CU: {0}; choosing '
'DEBUG'.format(die_name))
specific_build_type = SpecificImpaladBuildTypes.DEBUG