
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 llvm-svn: 245734
175 lines
4.5 KiB
C++
175 lines
4.5 KiB
C++
//===-- tsan_flags_test.cc ------------------------------------------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file is a part of ThreadSanitizer (TSan), a race detector.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
#include "tsan_flags.h"
|
|
#include "tsan_rtl.h"
|
|
#include "gtest/gtest.h"
|
|
#include <string>
|
|
|
|
namespace __tsan {
|
|
|
|
TEST(Flags, Basic) {
|
|
// At least should not crash.
|
|
Flags f;
|
|
InitializeFlags(&f, 0);
|
|
InitializeFlags(&f, "");
|
|
}
|
|
|
|
TEST(Flags, DefaultValues) {
|
|
Flags f;
|
|
|
|
f.enable_annotations = false;
|
|
InitializeFlags(&f, "");
|
|
EXPECT_EQ(true, f.enable_annotations);
|
|
}
|
|
|
|
static const char *options1 =
|
|
" enable_annotations=0"
|
|
" suppress_equal_stacks=0"
|
|
" suppress_equal_addresses=0"
|
|
" report_bugs=0"
|
|
" report_thread_leaks=0"
|
|
" report_destroy_locked=0"
|
|
" report_mutex_bugs=0"
|
|
" report_signal_unsafe=0"
|
|
" report_atomic_races=0"
|
|
" force_seq_cst_atomics=0"
|
|
" print_benign=0"
|
|
" halt_on_error=0"
|
|
" atexit_sleep_ms=222"
|
|
" profile_memory=qqq"
|
|
" flush_memory_ms=444"
|
|
" flush_symbolizer_ms=555"
|
|
" memory_limit_mb=666"
|
|
" stop_on_start=0"
|
|
" running_on_valgrind=0"
|
|
" history_size=5"
|
|
" io_sync=1"
|
|
" die_after_fork=true"
|
|
"";
|
|
|
|
static const char *options2 =
|
|
" enable_annotations=true"
|
|
" suppress_equal_stacks=true"
|
|
" suppress_equal_addresses=true"
|
|
" report_bugs=true"
|
|
" report_thread_leaks=true"
|
|
" report_destroy_locked=true"
|
|
" report_mutex_bugs=true"
|
|
" report_signal_unsafe=true"
|
|
" report_atomic_races=true"
|
|
" force_seq_cst_atomics=true"
|
|
" print_benign=true"
|
|
" halt_on_error=true"
|
|
" atexit_sleep_ms=123"
|
|
" profile_memory=bbbbb"
|
|
" flush_memory_ms=234"
|
|
" flush_symbolizer_ms=345"
|
|
" memory_limit_mb=456"
|
|
" stop_on_start=true"
|
|
" running_on_valgrind=true"
|
|
" history_size=6"
|
|
" io_sync=2"
|
|
" die_after_fork=false"
|
|
"";
|
|
|
|
void VerifyOptions1(Flags *f) {
|
|
EXPECT_EQ(f->enable_annotations, 0);
|
|
EXPECT_EQ(f->suppress_equal_stacks, 0);
|
|
EXPECT_EQ(f->suppress_equal_addresses, 0);
|
|
EXPECT_EQ(f->report_bugs, 0);
|
|
EXPECT_EQ(f->report_thread_leaks, 0);
|
|
EXPECT_EQ(f->report_destroy_locked, 0);
|
|
EXPECT_EQ(f->report_mutex_bugs, 0);
|
|
EXPECT_EQ(f->report_signal_unsafe, 0);
|
|
EXPECT_EQ(f->report_atomic_races, 0);
|
|
EXPECT_EQ(f->force_seq_cst_atomics, 0);
|
|
EXPECT_EQ(f->print_benign, 0);
|
|
EXPECT_EQ(f->halt_on_error, 0);
|
|
EXPECT_EQ(f->atexit_sleep_ms, 222);
|
|
EXPECT_EQ(f->profile_memory, std::string("qqq"));
|
|
EXPECT_EQ(f->flush_memory_ms, 444);
|
|
EXPECT_EQ(f->flush_symbolizer_ms, 555);
|
|
EXPECT_EQ(f->memory_limit_mb, 666);
|
|
EXPECT_EQ(f->stop_on_start, 0);
|
|
EXPECT_EQ(f->running_on_valgrind, 0);
|
|
EXPECT_EQ(f->history_size, 5);
|
|
EXPECT_EQ(f->io_sync, 1);
|
|
EXPECT_EQ(f->die_after_fork, true);
|
|
}
|
|
|
|
void VerifyOptions2(Flags *f) {
|
|
EXPECT_EQ(f->enable_annotations, true);
|
|
EXPECT_EQ(f->suppress_equal_stacks, true);
|
|
EXPECT_EQ(f->suppress_equal_addresses, true);
|
|
EXPECT_EQ(f->report_bugs, true);
|
|
EXPECT_EQ(f->report_thread_leaks, true);
|
|
EXPECT_EQ(f->report_destroy_locked, true);
|
|
EXPECT_EQ(f->report_mutex_bugs, true);
|
|
EXPECT_EQ(f->report_signal_unsafe, true);
|
|
EXPECT_EQ(f->report_atomic_races, true);
|
|
EXPECT_EQ(f->force_seq_cst_atomics, true);
|
|
EXPECT_EQ(f->print_benign, true);
|
|
EXPECT_EQ(f->halt_on_error, true);
|
|
EXPECT_EQ(f->atexit_sleep_ms, 123);
|
|
EXPECT_EQ(f->profile_memory, std::string("bbbbb"));
|
|
EXPECT_EQ(f->flush_memory_ms, 234);
|
|
EXPECT_EQ(f->flush_symbolizer_ms, 345);
|
|
EXPECT_EQ(f->memory_limit_mb, 456);
|
|
EXPECT_EQ(f->stop_on_start, true);
|
|
EXPECT_EQ(f->running_on_valgrind, true);
|
|
EXPECT_EQ(f->history_size, 6);
|
|
EXPECT_EQ(f->io_sync, 2);
|
|
EXPECT_EQ(f->die_after_fork, false);
|
|
}
|
|
|
|
static const char *test_default_options;
|
|
extern "C" const char *__tsan_default_options() {
|
|
return test_default_options;
|
|
}
|
|
|
|
TEST(Flags, ParseDefaultOptions) {
|
|
Flags f;
|
|
|
|
test_default_options = options1;
|
|
InitializeFlags(&f, "");
|
|
VerifyOptions1(&f);
|
|
|
|
test_default_options = options2;
|
|
InitializeFlags(&f, "");
|
|
VerifyOptions2(&f);
|
|
}
|
|
|
|
TEST(Flags, ParseEnvOptions) {
|
|
Flags f;
|
|
|
|
InitializeFlags(&f, options1);
|
|
VerifyOptions1(&f);
|
|
|
|
InitializeFlags(&f, options2);
|
|
VerifyOptions2(&f);
|
|
}
|
|
|
|
TEST(Flags, ParsePriority) {
|
|
Flags f;
|
|
|
|
test_default_options = options2;
|
|
InitializeFlags(&f, options1);
|
|
VerifyOptions1(&f);
|
|
|
|
test_default_options = options1;
|
|
InitializeFlags(&f, options2);
|
|
VerifyOptions2(&f);
|
|
}
|
|
|
|
} // namespace __tsan
|