summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--SConstruct38
-rw-r--r--etc/asan.blacklist0
-rw-r--r--etc/lsan.suppressions17
-rw-r--r--etc/tsan.blacklist0
-rw-r--r--etc/ubsan.blacklist0
-rw-r--r--src/mongo/util/concurrency/mutex.h5
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