From f0e050a5806cd4fe9a231374ad3d817408c726ea Mon Sep 17 00:00:00 2001 From: Andrew Morrow Date: Fri, 30 May 2014 14:38:37 -0400 Subject: [PATCH] SERVER-14105 Improve support for building with various sanitizers --- SConstruct | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/SConstruct b/SConstruct index eb9c6a3fa34..091650b3420 100644 --- a/SConstruct +++ b/SConstruct @@ -252,9 +252,8 @@ add_option( "dbg", "Enable runtime debugging checks", "?", True, "dbg", add_option( "opt", "Enable compile-time optimization", "?", True, "opt", type="choice", choices=["on", "off"], const="on" ) -sanitizer_choices = ["address", "memory", "thread", "undefined"] -add_option( "sanitize", "enable selected sanitizer", 1, True, - type="choice", choices=sanitizer_choices, default=None ) +add_option( "sanitize", "enable selected sanitizers", 1, True, metavar="san1,san2,...sanN" ) +add_option( "llvm-symbolizer", "name of (or path to) the LLVM symbolizer", 1, False, default="llvm-symbolizer" ) add_option( "durableDefaultOn" , "have durable default to on" , 0 , True ) add_option( "durableDefaultOff" , "have durable default to off" , 0 , True ) @@ -1345,17 +1344,48 @@ def doConfigure(myenv): conf.Finish() if has_option('sanitize'): + if not (using_clang() or using_gcc()): print( 'sanitize is only supported with clang or gcc') Exit(1) - sanitizer_option = '-fsanitize=' + GetOption('sanitize') + + sanitizer_list = get_option('sanitize').split(',') + + using_asan = 'address' in sanitizer_list or 'leak' in sanitizer_list + if using_asan: + if get_option('allocator') == 'tcmalloc': + print("Cannot use address or leak sanitizer with tcmalloc") + Exit(1) + + # If the user asked for leak sanitizer turn on the detect_leaks + # ASAN_OPTION. If they asked for address sanitizer as well, drop + # 'leak', because -fsanitize=leak means no address. + # + # --sanitize=leak: -fsanitize=leak, detect_leaks=1 + # --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 'address' in sanitizer_list: + sanitizer_list.remove('leak') + + sanitizer_option = '-fsanitize=' + ','.join(sanitizer_list) + if AddToCCFLAGSIfSupported(myenv, sanitizer_option): myenv.Append(LINKFLAGS=[sanitizer_option]) myenv.Append(CCFLAGS=['-fno-omit-frame-pointer']) else: - print( 'Failed to enable sanitizer with flag: ' + sanitizer_option ) + print( 'Failed to enable sanitizers with flag: ' + sanitizer_option ) Exit(1) + llvm_symbolizer = get_option('llvm-symbolizer') + if not os.path.isabs(llvm_symbolizer): + llvm_symbolizer = myenv.WhereIs(llvm_symbolizer) + if llvm_symbolizer: + if using_asan: + myenv['ENV']['ASAN_SYMBOLIZER_PATH'] = llvm_symbolizer + # When using msvc, check for VS 2013 Update 2+ so we can use new compiler flags if using_msvc(): haveVS2013Update2OrLater = False