diff options
-rw-r--r-- | SConstruct | 38 | ||||
-rw-r--r-- | etc/asan.blacklist | 0 | ||||
-rw-r--r-- | etc/lsan.suppressions | 17 | ||||
-rw-r--r-- | etc/tsan.blacklist | 0 | ||||
-rw-r--r-- | etc/ubsan.blacklist | 0 | ||||
-rw-r--r-- | src/mongo/util/concurrency/mutex.h | 5 |
6 files changed, 53 insertions, 7 deletions
diff --git a/SConstruct b/SConstruct index 092d86c10cf..9e216df2545 100644 --- a/SConstruct +++ b/SConstruct @@ -1552,7 +1552,9 @@ def doConfigure(myenv): sanitizer_list = get_option('sanitize').split(',') - using_asan = 'address' in sanitizer_list or 'leak' in sanitizer_list + using_lsan = 'leak' in sanitizer_list + using_asan = 'address' in sanitizer_list or using_lsan + if using_asan: if get_option('allocator') == 'tcmalloc': print("Cannot use address or leak sanitizer with tcmalloc") @@ -1566,8 +1568,10 @@ def doConfigure(myenv): # --sanitize=address,leak: -fsanitize=address, detect_leaks=1 # --sanitize=address: -fsanitize=address # - if 'leak' in sanitizer_list: - myenv['ENV']['ASAN_OPTIONS'] = "detect_leaks=1" + if using_lsan: + if using_asan: + myenv['ENV']['ASAN_OPTIONS'] = "detect_leaks=1" + myenv['ENV']['LSAN_OPTIONS'] = "suppressions=%s" % myenv.File("#etc/lsan.suppressions").abspath if 'address' in sanitizer_list: sanitizer_list.remove('leak') @@ -1580,12 +1584,34 @@ def doConfigure(myenv): print( 'Failed to enable sanitizers with flag: ' + sanitizer_option ) Exit(1) + blackfiles_map = { + "address" : myenv.File("#etc/asan.blacklist"), + "leak" : myenv.File("#etc/asan.blacklist"), + "thread" : myenv.File("#etc/tsan.blacklist"), + "undefined" : myenv.File("#etc/ubsan.blacklist"), + } + + blackfiles = set([v for (k, v) in blackfiles_map.iteritems() if k in sanitizer_list]) + blacklist_options=["-fsanitize-blacklist=%s" % blackfile for blackfile in blackfiles] + + for blacklist_option in blacklist_options: + if AddToCCFLAGSIfSupported(myenv, blacklist_option): + myenv.Append(LINKFLAGS=[blacklist_option]) + llvm_symbolizer = get_option('llvm-symbolizer') - if not os.path.isabs(llvm_symbolizer): + if os.path.isabs(llvm_symbolizer): + if not myenv.File(llvm_symbolizer).exists(): + print("WARNING: Specified symbolizer '%s' not found" % llvm_symbolizer) + llvm_symbolizer = None + else: llvm_symbolizer = myenv.WhereIs(llvm_symbolizer) + if llvm_symbolizer: - if using_asan: - myenv['ENV']['ASAN_SYMBOLIZER_PATH'] = llvm_symbolizer + myenv['ENV']['ASAN_SYMBOLIZER_PATH'] = llvm_symbolizer + myenv['ENV']['LSAN_SYMBOLIZER_PATH'] = llvm_symbolizer + elif using_lsan: + print("Using the leak sanitizer requires a valid symbolizer") + Exit(1) # When using msvc, # check for min version of VS2013 for fixes in std::list::splice diff --git a/etc/asan.blacklist b/etc/asan.blacklist new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/etc/asan.blacklist diff --git a/etc/lsan.suppressions b/etc/lsan.suppressions new file mode 100644 index 00000000000..7a0254dd41f --- /dev/null +++ b/etc/lsan.suppressions @@ -0,0 +1,17 @@ +# Client objects are leaked in threads that are never terminated +leak:mongo::Client::Client + +# Insanity related to the fact that the static observer +# prevents deleting mutexes during clean shutdown. If you +# remove the StaticObserver, remove this too. +leak:mongo::mutex::mutex + +# Thread names leak from threads that are never terminated. +leak:mongo::setThreadName + +# lets just ignore v8 for now. If we upgrade to newer v8 +# try removing this suppression +leak:v8:: + +# List1 is an abomination, as is its test. +leak:ThreadedTests::List1 diff --git a/etc/tsan.blacklist b/etc/tsan.blacklist new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/etc/tsan.blacklist diff --git a/etc/ubsan.blacklist b/etc/ubsan.blacklist new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/etc/ubsan.blacklist diff --git a/src/mongo/util/concurrency/mutex.h b/src/mongo/util/concurrency/mutex.h index db338730158..8ce3f1217c3 100644 --- a/src/mongo/util/concurrency/mutex.h +++ b/src/mongo/util/concurrency/mutex.h @@ -37,6 +37,7 @@ #include <boost/thread/mutex.hpp> #include <boost/thread/xtime.hpp> +#include "mongo/bson/inline_decls.h" #include "mongo/util/assert_util.h" #include "mongo/util/heapcheck.h" #include "mongo/util/concurrency/threadlocal.h" @@ -82,7 +83,9 @@ namespace mongo { class mutex : boost::noncopyable { public: const char * const _name; - mutex(const char *name) : _name(name) + // NOINLINE so that 'mutex::mutex' is always in the frame, this makes + // it easier for us to suppress the leaks caused by the static observer. + NOINLINE_DECL mutex(const char *name) : _name(name) { _m = new boost::timed_mutex(); IGNORE_OBJECT( _m ); // Turn-off heap checking on _m |