Index: lib/asan/asan_flags.inc =================================================================== --- lib/asan/asan_flags.inc +++ lib/asan/asan_flags.inc @@ -75,10 +75,6 @@ "295.*.") ASAN_FLAG(bool, unmap_shadow_on_exit, false, "If set, explicitly unmaps the (huge) shadow at exit.") -ASAN_FLAG( - bool, abort_on_error, SANITIZER_MAC, - "If set, the tool calls abort() instead of _exit() after printing the " - "error report.") ASAN_FLAG(bool, print_stats, false, "Print various statistics after printing an error message or if " "atexit=1.") Index: lib/asan/asan_rtl.cc =================================================================== --- lib/asan/asan_rtl.cc +++ lib/asan/asan_rtl.cc @@ -56,8 +56,6 @@ UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg); } } - if (flags()->abort_on_error) - Abort(); } static void AsanCheckFailed(const char *file, int line, const char *cond, Index: lib/sanitizer_common/sanitizer_common.cc =================================================================== --- lib/sanitizer_common/sanitizer_common.cc +++ lib/sanitizer_common/sanitizer_common.cc @@ -142,6 +142,8 @@ if (InternalDieCallbacks[i]) InternalDieCallbacks[i](); } + if (common_flags()->abort_on_error) + Abort(); internal__exit(common_flags()->exitcode); } Index: lib/sanitizer_common/sanitizer_common_nolibc.cc =================================================================== --- lib/sanitizer_common/sanitizer_common_nolibc.cc +++ lib/sanitizer_common/sanitizer_common_nolibc.cc @@ -13,6 +13,7 @@ #include "sanitizer_platform.h" #include "sanitizer_common.h" +#include "sanitizer_libc.h" namespace __sanitizer { @@ -20,4 +21,6 @@ void WriteToSyslog(const char *buffer) {} #endif -} +void Abort() { internal__exit(1); } + +} // namespace __sanitizer Index: lib/sanitizer_common/sanitizer_flags.inc =================================================================== --- lib/sanitizer_common/sanitizer_flags.inc +++ lib/sanitizer_common/sanitizer_flags.inc @@ -187,3 +187,7 @@ "user-readable names") COMMON_FLAG(int, exitcode, 1, "Override the program exit status if the tool " "found an error") +COMMON_FLAG( + bool, abort_on_error, SANITIZER_MAC, + "If set, the tool calls abort() instead of _exit() after printing the " + "error report.") Index: test/sanitizer_common/TestCases/Darwin/abort_on_error.cc =================================================================== --- /dev/null +++ test/sanitizer_common/TestCases/Darwin/abort_on_error.cc @@ -0,0 +1,19 @@ +// Check that sanitizers on OS X crash the process by default (i.e. +// abort_on_error=1). See also Linux/abort_on_error.cc. + +// RUN: %clangxx %s -o %t + +// Intentionally don't inherit the default options. +// RUN: %env_tool_opts='' not --crash %run %t 2>&1 + +// When we use lit's default options, we shouldn't crash. +// RUN: not %run %t 2>&1 + +int global; + +int main() { + volatile int *a = new int[100]; + delete[] a; + global = a[0]; // use-after-free: triggers ASan report. + return 0; +} Index: test/sanitizer_common/TestCases/Darwin/lit.local.cfg =================================================================== --- /dev/null +++ test/sanitizer_common/TestCases/Darwin/lit.local.cfg @@ -0,0 +1,9 @@ +def getRoot(config): + if not config.parent: + return config + return getRoot(config.parent) + +root = getRoot(config) + +if root.host_os not in ['Darwin']: + config.unsupported = True Index: test/sanitizer_common/TestCases/Linux/abort_on_error.cc =================================================================== --- /dev/null +++ test/sanitizer_common/TestCases/Linux/abort_on_error.cc @@ -0,0 +1,20 @@ +// Check that sanitizers call _exit() on Linux by default (i.e. +// abort_on_error=0). See also Darwin/abort_on_error.cc. + +// RUN: %clangxx %s -o %t + +// Intentionally don't inherit the default options. +// RUN: %env_tool_opts='' not %run %t 2>&1 + +// When we use lit's default options, we shouldn't crash either. On Linux +// lit doesn't set options anyway. +// RUN: not %run %t 2>&1 + +namespace __sanitizer { +void Die(); +} + +int main() { + __sanitizer::Die(); + return 0; +} Index: test/sanitizer_common/lit.common.cfg =================================================================== --- test/sanitizer_common/lit.common.cfg +++ test/sanitizer_common/lit.common.cfg @@ -5,6 +5,7 @@ config.name = "SanitizerCommon-" + config.tool_name +default_tool_options = [] if config.tool_name == "asan": tool_cflags = ["-fsanitize=address"] tool_options = "ASAN_OPTIONS" @@ -22,6 +23,15 @@ config.available_features.add(config.tool_name) +if config.host_os == 'Darwin': + # On Darwin, we default to `abort_on_error=1`, which would make tests run + # much slower. Let's override this and run lit tests with 'abort_on_error=0'. + default_tool_options += ['abort_on_error=0'] +default_tool_options_str = ':'.join(default_tool_options) +if default_tool_options_str: + config.environment[tool_options] = default_tool_options_str + default_tool_options_str += ':' + clang_cflags = config.debug_info_flags + tool_cflags + [config.target_cflags] clang_cxxflags = config.cxx_mode_flags + clang_cflags @@ -31,7 +41,6 @@ config.substitutions.append( ("%clang ", build_invocation(clang_cflags)) ) config.substitutions.append( ("%clangxx ", build_invocation(clang_cxxflags)) ) config.substitutions.append( ("%tool_name", config.tool_name) ) -default_tool_options_str = '' config.substitutions.append( ('%env_tool_opts=', 'env ' + tool_options + '=' + default_tool_options_str)) Index: test/ubsan/lit.common.cfg =================================================================== --- test/ubsan/lit.common.cfg +++ test/ubsan/lit.common.cfg @@ -14,6 +14,7 @@ # Setup source root. config.test_source_root = os.path.dirname(__file__) +default_ubsan_opts = [] # Choose between standalone and UBSan+ASan modes. ubsan_lit_test_mode = get_required_attr(config, 'ubsan_lit_test_mode') if ubsan_lit_test_mode == "Standalone": @@ -24,13 +25,7 @@ config.name = 'UBSan-ASan-' + config.target_arch config.available_features.add("ubsan-asan") clang_ubsan_cflags = ["-fsanitize=address"] - config.environment['ASAN_OPTIONS'] = 'detect_leaks=0' - - # Platform-specific default ASAN_OPTIONS for lit tests. - if config.host_os == 'Darwin': - # On Darwin, we default to `abort_on_error=1`, which would make tests run - # much slower. Let's override this and run lit tests with 'abort_on_error=0'. - config.environment['ASAN_OPTIONS'] = 'abort_on_error=0' + default_ubsan_opts += ['detect_leaks=0'] elif ubsan_lit_test_mode == "MemorySanitizer": config.name = 'UBSan-MSan-' + config.target_arch config.available_features.add("ubsan-msan") @@ -42,9 +37,18 @@ else: lit_config.fatal("Unknown UBSan test mode: %r" % ubsan_lit_test_mode) +# Platform-specific default for lit tests. +if config.host_os == 'Darwin': + # On Darwin, we default to `abort_on_error=1`, which would make tests run + # much slower. Let's override this and run lit tests with 'abort_on_error=0'. + default_ubsan_opts += ['abort_on_error=0'] +default_ubsan_opts_str = ':'.join(default_ubsan_opts) +if default_ubsan_opts_str: + config.environment['UBSAN_OPTIONS'] = default_ubsan_opts_str + default_ubsan_opts_str += ':' # Substitution to setup UBSAN_OPTIONS in portable way. config.substitutions.append(('%env_ubsan_opts=', - 'env UBSAN_OPTIONS=')) + 'env UBSAN_OPTIONS=' + default_ubsan_opts_str)) def build_invocation(compile_flags): return " " + " ".join([config.clang] + compile_flags) + " "