[Sanitizers] Make abort_on_error common flag.

Summary:
Teach all sanitizers to call abort() instead of _exit() after printing
an error report, if requested. This behavior is the default on Mac OS.

Reviewers: kcc, kubabrecka

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D12332

llvm-svn: 246205
This commit is contained in:
Alexey Samsonov 2015-08-27 20:40:24 +00:00
parent 9362270f78
commit 53b8750e7d
10 changed files with 81 additions and 16 deletions

View File

@ -75,10 +75,6 @@ ASAN_FLAG(bool, check_malloc_usable_size, true,
"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.")

View File

@ -56,8 +56,6 @@ static void AsanDie() {
UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg);
}
}
if (flags()->abort_on_error)
Abort();
}
static void AsanCheckFailed(const char *file, int line, const char *cond,

View File

@ -143,6 +143,8 @@ void NORETURN Die() {
if (InternalDieCallbacks[i])
InternalDieCallbacks[i]();
}
if (common_flags()->abort_on_error)
Abort();
internal__exit(common_flags()->exitcode);
}

View File

@ -13,6 +13,7 @@
#include "sanitizer_platform.h"
#include "sanitizer_common.h"
#include "sanitizer_libc.h"
namespace __sanitizer {
@ -20,4 +21,6 @@ namespace __sanitizer {
void WriteToSyslog(const char *buffer) {}
#endif
}
void Abort() { internal__exit(1); }
} // namespace __sanitizer

View File

@ -187,3 +187,7 @@ COMMON_FLAG(bool, decorate_proc_maps, false, "If set, decorate sanitizer "
"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.")

View File

@ -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: %tool_options='' 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;
}

View File

@ -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

View File

@ -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: %tool_options='' 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;
}

View File

@ -5,6 +5,7 @@ config.test_source_root = os.path.join(os.path.dirname(__file__), "TestCases")
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 @@ else:
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,7 @@ def build_invocation(compile_flags):
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( ("%tool_options", tool_options) )
config.substitutions.append( ('%env_tool_opts=',
'env ' + tool_options + '=' + default_tool_options_str))

View File

@ -14,6 +14,7 @@ def get_required_attr(config, attr_name):
# 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 @@ elif ubsan_lit_test_mode == "AddressSanitizer":
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 @@ elif ubsan_lit_test_mode == "ThreadSanitizer":
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) + " "