summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Samsonov <vonosmas@gmail.com>2015-08-21 20:49:37 +0000
committerAlexey Samsonov <vonosmas@gmail.com>2015-08-21 20:49:37 +0000
commit23b3d26ca5e3f782373f73620d7872dc0fc1c0b2 (patch)
treec0cc0f0de1a49054359e7b85e7f3d1fb6eeef180
parent564ca11c1e257ea6207a50bbfe36be4ecc29fe5f (diff)
[Sanitizers] Unify the semantics and usage of "exitcode" runtime flag across all sanitizers.
Summary: Merge "exitcode" flag from ASan, LSan, TSan and "exit_code" from MSan into one entity. Additionally, make sure sanitizer_common now uses the value of common_flags()->exitcode when dying on error, so that this flag will automatically work for other sanitizers (UBSan and DFSan) as well. User-visible changes: * "exit_code" MSan runtime flag is now deprecated. If explicitly specified, this flag will take precedence over "exitcode". The users are encouraged to migrate to the new version. * __asan_set_error_exit_code() and __msan_set_exit_code() functions are removed. With few exceptions, we don't support changing runtime flags during program execution - we can't make them thread-safe. The users should use __sanitizer_set_death_callback() that would call _exit() with proper exit code instead. * Plugin tools (LSan and UBSan) now inherit the exit code of the parent tool. In particular, this means that ASan would now crash the program with exit code "1" instead of "23" if it detects leaks. Reviewers: kcc, eugenis Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D12120 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@245734 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/sanitizer/asan_interface.h4
-rw-r--r--include/sanitizer/lsan_interface.h2
-rw-r--r--include/sanitizer/msan_interface.h4
-rw-r--r--lib/asan/asan_flags.cc1
-rw-r--r--lib/asan/asan_flags.inc2
-rw-r--r--lib/asan/asan_interface_internal.h2
-rw-r--r--lib/asan/asan_internal.h2
-rw-r--r--lib/asan/asan_report.cc2
-rw-r--r--lib/asan/asan_rtl.cc8
-rw-r--r--lib/asan/tests/asan_interface_test.cc10
-rw-r--r--lib/lsan/lsan.cc1
-rw-r--r--lib/lsan/lsan_common.cc4
-rw-r--r--lib/lsan/lsan_flags.inc2
-rw-r--r--lib/msan/msan.cc20
-rw-r--r--lib/msan/msan_flags.inc3
-rw-r--r--lib/msan/msan_interface_internal.h6
-rw-r--r--lib/msan/msan_linux.cc4
-rw-r--r--lib/sanitizer_common/sanitizer_common.cc2
-rw-r--r--lib/sanitizer_common/sanitizer_flags.inc2
-rw-r--r--lib/tsan/rtl/tsan_flags.cc1
-rw-r--r--lib/tsan/rtl/tsan_flags.inc1
-rw-r--r--lib/tsan/rtl/tsan_rtl.cc2
-rw-r--r--lib/tsan/rtl/tsan_rtl_report.cc2
-rw-r--r--lib/tsan/tests/unit/tsan_flags_test.cc6
24 files changed, 29 insertions, 64 deletions
diff --git a/include/sanitizer/asan_interface.h b/include/sanitizer/asan_interface.h
index 7763389ab..97ba0ceb0 100644
--- a/include/sanitizer/asan_interface.h
+++ b/include/sanitizer/asan_interface.h
@@ -110,10 +110,6 @@ extern "C" {
void __asan_report_error(void *pc, void *bp, void *sp,
void *addr, int is_write, size_t access_size);
- // Sets the exit code to use when reporting an error.
- // Returns the old value.
- int __asan_set_error_exit_code(int exit_code);
-
// Deprecated. Call __sanitizer_set_death_callback instead.
void __asan_set_death_callback(void (*callback)(void));
diff --git a/include/sanitizer/lsan_interface.h b/include/sanitizer/lsan_interface.h
index db017c4de..8fb8e756d 100644
--- a/include/sanitizer/lsan_interface.h
+++ b/include/sanitizer/lsan_interface.h
@@ -43,7 +43,7 @@ extern "C" {
// Check for leaks now. This function behaves identically to the default
// end-of-process leak check. In particular, it will terminate the process if
- // leaks are found and the exit_code flag is non-zero.
+ // leaks are found and the exitcode runtime flag is non-zero.
// Subsequent calls to this function will have no effect and end-of-process
// leak check will not run. Effectively, end-of-process leak check is moved to
// the time of first invocation of this function.
diff --git a/include/sanitizer/msan_interface.h b/include/sanitizer/msan_interface.h
index 703313503..9aa44a010 100644
--- a/include/sanitizer/msan_interface.h
+++ b/include/sanitizer/msan_interface.h
@@ -61,10 +61,6 @@ extern "C" {
* is not. */
void __msan_check_mem_is_initialized(const volatile void *x, size_t size);
- /* Set exit code when error(s) were detected.
- Value of 0 means don't change the program exit code. */
- void __msan_set_exit_code(int exit_code);
-
/* For testing:
__msan_set_expect_umr(1);
... some buggy code ...
diff --git a/lib/asan/asan_flags.cc b/lib/asan/asan_flags.cc
index e8ea549b6..18e597ffa 100644
--- a/lib/asan/asan_flags.cc
+++ b/lib/asan/asan_flags.cc
@@ -65,6 +65,7 @@ void InitializeFlags() {
cf.external_symbolizer_path = GetEnv("ASAN_SYMBOLIZER_PATH");
cf.malloc_context_size = kDefaultMallocContextSize;
cf.intercept_tls_get_addr = true;
+ cf.exitcode = 1;
OverrideCommonFlags(cf);
}
Flags *f = flags();
diff --git a/lib/asan/asan_flags.inc b/lib/asan/asan_flags.inc
index 7e864b559..56fd3d1df 100644
--- a/lib/asan/asan_flags.inc
+++ b/lib/asan/asan_flags.inc
@@ -62,8 +62,6 @@ ASAN_FLAG(
"bytes that will be filled with malloc_fill_byte on malloc.")
ASAN_FLAG(int, malloc_fill_byte, 0xbe,
"Value used to fill the newly allocated memory.")
-ASAN_FLAG(int, exitcode, ASAN_DEFAULT_FAILURE_EXITCODE,
- "Override the program exit status if the tool found an error.")
ASAN_FLAG(bool, allow_user_poisoning, true,
"If set, user may manually mark memory regions as poisoned or "
"unpoisoned.")
diff --git a/lib/asan/asan_interface_internal.h b/lib/asan/asan_interface_internal.h
index addfb6743..18cd2b6de 100644
--- a/lib/asan/asan_interface_internal.h
+++ b/lib/asan/asan_interface_internal.h
@@ -135,8 +135,6 @@ extern "C" {
uptr addr, int is_write, uptr access_size, u32 exp);
SANITIZER_INTERFACE_ATTRIBUTE
- int __asan_set_error_exit_code(int exit_code);
- SANITIZER_INTERFACE_ATTRIBUTE
void __asan_set_death_callback(void (*callback)(void));
SANITIZER_INTERFACE_ATTRIBUTE
void __asan_set_error_report_callback(void (*callback)(const char*));
diff --git a/lib/asan/asan_internal.h b/lib/asan/asan_internal.h
index 715559fbb..9e9175879 100644
--- a/lib/asan/asan_internal.h
+++ b/lib/asan/asan_internal.h
@@ -21,8 +21,6 @@
#include "sanitizer_common/sanitizer_stacktrace.h"
#include "sanitizer_common/sanitizer_libc.h"
-#define ASAN_DEFAULT_FAILURE_EXITCODE 1
-
#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
# error "The AddressSanitizer run-time should not be"
" instrumented by AddressSanitizer"
diff --git a/lib/asan/asan_report.cc b/lib/asan/asan_report.cc
index 2d0d3b308..1cc45ddee 100644
--- a/lib/asan/asan_report.cc
+++ b/lib/asan/asan_report.cc
@@ -639,7 +639,7 @@ class ScopedInErrorReport {
}
// If we're still not dead for some reason, use raw _exit() instead of
// Die() to bypass any additional checks.
- internal__exit(flags()->exitcode);
+ internal__exit(common_flags()->exitcode);
}
if (report) report_data = *report;
report_happened = true;
diff --git a/lib/asan/asan_rtl.cc b/lib/asan/asan_rtl.cc
index 7ff657bc5..ad5a8eb98 100644
--- a/lib/asan/asan_rtl.cc
+++ b/lib/asan/asan_rtl.cc
@@ -60,7 +60,6 @@ static void AsanDie() {
__sanitizer_cov_dump();
if (flags()->abort_on_error)
Abort();
- internal__exit(flags()->exitcode);
}
static void AsanCheckFailed(const char *file, int line, const char *cond,
@@ -267,7 +266,6 @@ static NOINLINE void force_interface_symbols() {
case 30: __asan_address_is_poisoned(0); break;
case 31: __asan_poison_memory_region(0, 0); break;
case 32: __asan_unpoison_memory_region(0, 0); break;
- case 33: __asan_set_error_exit_code(0); break;
case 34: __asan_before_dynamic_init(0); break;
case 35: __asan_after_dynamic_init(); break;
case 36: __asan_poison_stack_memory(0, 0); break;
@@ -550,12 +548,6 @@ static AsanInitializer asan_initializer;
// ---------------------- Interface ---------------- {{{1
using namespace __asan; // NOLINT
-int NOINLINE __asan_set_error_exit_code(int exit_code) {
- int old = flags()->exitcode;
- flags()->exitcode = exit_code;
- return old;
-}
-
void NOINLINE __asan_handle_no_return() {
int local_stack;
AsanThread *curr_thread = GetCurrentThread();
diff --git a/lib/asan/tests/asan_interface_test.cc b/lib/asan/tests/asan_interface_test.cc
index a34c8528e..f5bfb8046 100644
--- a/lib/asan/tests/asan_interface_test.cc
+++ b/lib/asan/tests/asan_interface_test.cc
@@ -140,16 +140,6 @@ static void DoDoubleFree() {
delete Ident(x);
}
-TEST(AddressSanitizerInterface, ExitCode) {
- int original_exit_code = __asan_set_error_exit_code(7);
- EXPECT_EXIT(DoDoubleFree(), ::testing::ExitedWithCode(7), "");
- EXPECT_EQ(7, __asan_set_error_exit_code(8));
- EXPECT_EXIT(DoDoubleFree(), ::testing::ExitedWithCode(8), "");
- EXPECT_EQ(8, __asan_set_error_exit_code(original_exit_code));
- EXPECT_EXIT(DoDoubleFree(),
- ::testing::ExitedWithCode(original_exit_code), "");
-}
-
static void MyDeathCallback() {
fprintf(stderr, "MyDeathCallback\n");
fflush(0); // On Windows, stderr doesn't flush on crash.
diff --git a/lib/lsan/lsan.cc b/lib/lsan/lsan.cc
index 91c29b9c1..f3e6ad7c9 100644
--- a/lib/lsan/lsan.cc
+++ b/lib/lsan/lsan.cc
@@ -44,6 +44,7 @@ static void InitializeFlags() {
cf.external_symbolizer_path = GetEnv("LSAN_SYMBOLIZER_PATH");
cf.malloc_context_size = 30;
cf.detect_leaks = true;
+ cf.exitcode = 23;
OverrideCommonFlags(cf);
}
diff --git a/lib/lsan/lsan_common.cc b/lib/lsan/lsan_common.cc
index 0ffba505c..46daefeeb 100644
--- a/lib/lsan/lsan_common.cc
+++ b/lib/lsan/lsan_common.cc
@@ -444,10 +444,10 @@ void DoLeakCheck() {
if (!have_leaks) {
return;
}
- if (flags()->exitcode) {
+ if (common_flags()->exitcode) {
if (common_flags()->coverage)
__sanitizer_cov_dump();
- internal__exit(flags()->exitcode);
+ internal__exit(common_flags()->exitcode);
}
}
diff --git a/lib/lsan/lsan_flags.inc b/lib/lsan/lsan_flags.inc
index b19b3452b..c405005de 100644
--- a/lib/lsan/lsan_flags.inc
+++ b/lib/lsan/lsan_flags.inc
@@ -24,8 +24,6 @@ LSAN_FLAG(
"Aggregate two objects into one leak if this many stack frames match. If "
"zero, the entire stack trace must match.")
LSAN_FLAG(int, max_leaks, 0, "The number of leaks reported.")
-LSAN_FLAG(int, exitcode, 23,
- "If nonzero kill the process with this exit code upon finding leaks.")
// Flags controlling the root set of reachable memory.
LSAN_FLAG(bool, use_globals, true,
diff --git a/lib/msan/msan.cc b/lib/msan/msan.cc
index d75c280ad..1d2767d8d 100644
--- a/lib/msan/msan.cc
+++ b/lib/msan/msan.cc
@@ -145,6 +145,7 @@ static void InitializeFlags() {
// FIXME: test and enable.
cf.check_printf = false;
cf.intercept_tls_get_addr = true;
+ cf.exitcode = 77;
OverrideCommonFlags(cf);
}
@@ -185,11 +186,18 @@ static void InitializeFlags() {
if (common_flags()->help) parser.PrintFlagDescriptions();
- // Check flag values:
- if (f->exit_code < 0 || f->exit_code > 127) {
- Printf("Exit code not in [0, 128) range: %d\n", f->exit_code);
- Die();
+ // Check if deprecated exit_code MSan flag is set.
+ if (f->exit_code != -1) {
+ if (Verbosity())
+ Printf("MSAN_OPTIONS=exit_code is deprecated! "
+ "Please use MSAN_OPTIONS=exitcode instead.\n");
+ CommonFlags cf;
+ cf.CopyFrom(*common_flags());
+ cf.exitcode = f->exit_code;
+ OverrideCommonFlags(cf);
}
+
+ // Check flag values:
if (f->origin_history_size < 0 ||
f->origin_history_size > Origin::kMaxDepth) {
Printf(
@@ -421,10 +429,6 @@ void __msan_init() {
msan_inited = 1;
}
-void __msan_set_exit_code(int exit_code) {
- flags()->exit_code = exit_code;
-}
-
void __msan_set_keep_going(int keep_going) {
flags()->halt_on_error = !keep_going;
}
diff --git a/lib/msan/msan_flags.inc b/lib/msan/msan_flags.inc
index 3729b3fc4..a7ff6c586 100644
--- a/lib/msan/msan_flags.inc
+++ b/lib/msan/msan_flags.inc
@@ -17,7 +17,8 @@
// MSAN_FLAG(Type, Name, DefaultValue, Description)
// See COMMON_FLAG in sanitizer_flags.inc for more details.
-MSAN_FLAG(int, exit_code, 77, "")
+MSAN_FLAG(int, exit_code, -1,
+ "DEPRECATED. Use exitcode from common flags instead.")
MSAN_FLAG(int, origin_history_size, Origin::kMaxDepth, "")
MSAN_FLAG(int, origin_history_per_stack_limit, 20000, "")
MSAN_FLAG(bool, poison_heap_with_zeroes, false, "")
diff --git a/lib/msan/msan_interface_internal.h b/lib/msan/msan_interface_internal.h
index 3b0e30c56..7340a34ca 100644
--- a/lib/msan/msan_interface_internal.h
+++ b/lib/msan/msan_interface_internal.h
@@ -27,7 +27,7 @@ SANITIZER_INTERFACE_ATTRIBUTE
void __msan_init();
// Print a warning and maybe return.
-// This function can die based on flags()->exit_code.
+// This function can die based on common_flags()->exitcode.
SANITIZER_INTERFACE_ATTRIBUTE
void __msan_warning();
@@ -106,10 +106,6 @@ int __msan_origin_is_descendant_or_same(u32 this_id, u32 prev_id);
SANITIZER_INTERFACE_ATTRIBUTE
void __msan_clear_on_return();
-// Default: -1 (don't exit on error).
-SANITIZER_INTERFACE_ATTRIBUTE
-void __msan_set_exit_code(int exit_code);
-
SANITIZER_INTERFACE_ATTRIBUTE
void __msan_set_keep_going(int keep_going);
diff --git a/lib/msan/msan_linux.cc b/lib/msan/msan_linux.cc
index 7025ef6c8..9e971994d 100644
--- a/lib/msan/msan_linux.cc
+++ b/lib/msan/msan_linux.cc
@@ -156,7 +156,6 @@ void MsanDie() {
__sanitizer_cov_dump();
if (death_callback)
death_callback();
- internal__exit(flags()->exit_code);
}
static void MsanAtExit(void) {
@@ -164,7 +163,8 @@ static void MsanAtExit(void) {
ReportStats();
if (msan_report_count > 0) {
ReportAtExitStatistics();
- if (flags()->exit_code) _exit(flags()->exit_code);
+ if (common_flags()->exitcode)
+ internal__exit(common_flags()->exitcode);
}
}
diff --git a/lib/sanitizer_common/sanitizer_common.cc b/lib/sanitizer_common/sanitizer_common.cc
index 8951c7985..fb0cee0f4 100644
--- a/lib/sanitizer_common/sanitizer_common.cc
+++ b/lib/sanitizer_common/sanitizer_common.cc
@@ -122,7 +122,7 @@ void NORETURN Die() {
UserDieCallback();
if (InternalDieCallback)
InternalDieCallback();
- internal__exit(1);
+ internal__exit(common_flags()->exitcode);
}
static CheckFailedCallbackType CheckFailedCallback;
diff --git a/lib/sanitizer_common/sanitizer_flags.inc b/lib/sanitizer_common/sanitizer_flags.inc
index 80931338c..2e610892d 100644
--- a/lib/sanitizer_common/sanitizer_flags.inc
+++ b/lib/sanitizer_common/sanitizer_flags.inc
@@ -185,3 +185,5 @@ COMMON_FLAG(bool, strict_memcmp, true,
COMMON_FLAG(bool, decorate_proc_maps, false, "If set, decorate sanitizer "
"mappings in /proc/self/maps with "
"user-readable names")
+COMMON_FLAG(int, exitcode, 1, "Override the program exit status if the tool "
+ "found an error")
diff --git a/lib/tsan/rtl/tsan_flags.cc b/lib/tsan/rtl/tsan_flags.cc
index 5de227a42..b8bee70b7 100644
--- a/lib/tsan/rtl/tsan_flags.cc
+++ b/lib/tsan/rtl/tsan_flags.cc
@@ -66,6 +66,7 @@ void InitializeFlags(Flags *f, const char *env) {
#endif
cf.print_suppressions = false;
cf.stack_trace_format = " #%n %f %S %M";
+ cf.exitcode = 66;
OverrideCommonFlags(cf);
}
diff --git a/lib/tsan/rtl/tsan_flags.inc b/lib/tsan/rtl/tsan_flags.inc
index e4994685f..ab9ca9924 100644
--- a/lib/tsan/rtl/tsan_flags.inc
+++ b/lib/tsan/rtl/tsan_flags.inc
@@ -45,7 +45,6 @@ TSAN_FLAG(
"If set, all atomics are effectively sequentially consistent (seq_cst), "
"regardless of what user actually specified.")
TSAN_FLAG(bool, print_benign, false, "Print matched \"benign\" races at exit.")
-TSAN_FLAG(int, exitcode, 66, "Override exit status if something was reported.")
TSAN_FLAG(bool, halt_on_error, false, "Exit after first reported error.")
TSAN_FLAG(int, atexit_sleep_ms, 1000,
"Sleep in main thread before exiting for that many ms "
diff --git a/lib/tsan/rtl/tsan_rtl.cc b/lib/tsan/rtl/tsan_rtl.cc
index 9ec84b881..264fdf902 100644
--- a/lib/tsan/rtl/tsan_rtl.cc
+++ b/lib/tsan/rtl/tsan_rtl.cc
@@ -417,7 +417,7 @@ int Finalize(ThreadState *thr) {
StatOutput(ctx->stat);
#endif
- return failed ? flags()->exitcode : 0;
+ return failed ? common_flags()->exitcode : 0;
}
#ifndef SANITIZER_GO
diff --git a/lib/tsan/rtl/tsan_rtl_report.cc b/lib/tsan/rtl/tsan_rtl_report.cc
index 6d4ab28e4..12e7ad68c 100644
--- a/lib/tsan/rtl/tsan_rtl_report.cc
+++ b/lib/tsan/rtl/tsan_rtl_report.cc
@@ -514,7 +514,7 @@ bool OutputReport(ThreadState *thr, const ScopedReport &srep) {
PrintReport(rep);
ctx->nreported++;
if (flags()->halt_on_error)
- internal__exit(flags()->exitcode);
+ internal__exit(common_flags()->exitcode);
return true;
}
diff --git a/lib/tsan/tests/unit/tsan_flags_test.cc b/lib/tsan/tests/unit/tsan_flags_test.cc
index 22610c0dc..aa8a024f9 100644
--- a/lib/tsan/tests/unit/tsan_flags_test.cc
+++ b/lib/tsan/tests/unit/tsan_flags_test.cc
@@ -28,9 +28,7 @@ TEST(Flags, DefaultValues) {
Flags f;
f.enable_annotations = false;
- f.exitcode = -11;
InitializeFlags(&f, "");
- EXPECT_EQ(66, f.exitcode);
EXPECT_EQ(true, f.enable_annotations);
}
@@ -46,7 +44,6 @@ static const char *options1 =
" report_atomic_races=0"
" force_seq_cst_atomics=0"
" print_benign=0"
- " exitcode=111"
" halt_on_error=0"
" atexit_sleep_ms=222"
" profile_memory=qqq"
@@ -72,7 +69,6 @@ static const char *options2 =
" report_atomic_races=true"
" force_seq_cst_atomics=true"
" print_benign=true"
- " exitcode=222"
" halt_on_error=true"
" atexit_sleep_ms=123"
" profile_memory=bbbbb"
@@ -98,7 +94,6 @@ void VerifyOptions1(Flags *f) {
EXPECT_EQ(f->report_atomic_races, 0);
EXPECT_EQ(f->force_seq_cst_atomics, 0);
EXPECT_EQ(f->print_benign, 0);
- EXPECT_EQ(f->exitcode, 111);
EXPECT_EQ(f->halt_on_error, 0);
EXPECT_EQ(f->atexit_sleep_ms, 222);
EXPECT_EQ(f->profile_memory, std::string("qqq"));
@@ -124,7 +119,6 @@ void VerifyOptions2(Flags *f) {
EXPECT_EQ(f->report_atomic_races, true);
EXPECT_EQ(f->force_seq_cst_atomics, true);
EXPECT_EQ(f->print_benign, true);
- EXPECT_EQ(f->exitcode, 222);
EXPECT_EQ(f->halt_on_error, true);
EXPECT_EQ(f->atexit_sleep_ms, 123);
EXPECT_EQ(f->profile_memory, std::string("bbbbb"));