[TSan] Use common flags in the same way as all the other sanitizers

llvm-svn: 217559
This commit is contained in:
Alexey Samsonov 2014-09-10 23:08:06 +00:00
parent 611c906cb3
commit 5c825967ea
8 changed files with 37 additions and 116 deletions

View File

@ -93,21 +93,19 @@ void InitializeFlags(Flags *f, const char *env) {
// DDFlags
f->second_deadlock_stack = false;
SetCommonFlagsDefaults(f);
CommonFlags *cf = common_flags();
SetCommonFlagsDefaults(cf);
// Override some common flags defaults.
f->allow_addr2line = true;
f->detect_deadlocks = true;
f->print_suppressions = false;
cf->allow_addr2line = true;
cf->detect_deadlocks = true;
cf->print_suppressions = false;
// Let a frontend override.
ParseFlags(f, __tsan_default_options());
ParseCommonFlagsFromString(f, __tsan_default_options());
ParseCommonFlagsFromString(cf, __tsan_default_options());
// Override from command line.
ParseFlags(f, env);
ParseCommonFlagsFromString(f, env);
// Copy back to common flags.
internal_memcpy(common_flags(), f, sizeof(*common_flags()));
ParseCommonFlagsFromString(cf, env);
// Sanity check.
if (!f->report_bugs) {
@ -116,7 +114,7 @@ void InitializeFlags(Flags *f, const char *env) {
f->report_signal_unsafe = false;
}
if (f->help) PrintFlagDescriptions();
if (cf->help) PrintFlagDescriptions();
if (f->history_size < 0 || f->history_size > 7) {
Printf("ThreadSanitizer: incorrect value for history_size"

View File

@ -19,7 +19,7 @@
namespace __tsan {
struct Flags : CommonFlags, DDFlags {
struct Flags : DDFlags {
// Enable dynamic annotations, otherwise they are no-ops.
bool enable_annotations;
// Suppress a race report if we've already output another race report

View File

@ -167,8 +167,7 @@ static void BackgroundThread(void *arg) {
// Flush memory if requested.
if (flags()->flush_memory_ms > 0) {
if (last_flush + flags()->flush_memory_ms * kMs2Ns < now) {
if (flags()->verbosity > 0)
Printf("ThreadSanitizer: periodic memory flush\n");
VPrintf(1, "ThreadSanitizer: periodic memory flush\n");
FlushShadowMemory();
last_flush = NanoTime();
}
@ -177,18 +176,14 @@ static void BackgroundThread(void *arg) {
if (flags()->memory_limit_mb > 0) {
uptr rss = GetRSS();
uptr limit = uptr(flags()->memory_limit_mb) << 20;
if (flags()->verbosity > 0) {
Printf("ThreadSanitizer: memory flush check"
" RSS=%llu LAST=%llu LIMIT=%llu\n",
(u64)rss>>20, (u64)last_rss>>20, (u64)limit>>20);
}
VPrintf(1, "ThreadSanitizer: memory flush check"
" RSS=%llu LAST=%llu LIMIT=%llu\n",
(u64)rss >> 20, (u64)last_rss >> 20, (u64)limit >> 20);
if (2 * rss > limit + last_rss) {
if (flags()->verbosity > 0)
Printf("ThreadSanitizer: flushing memory due to RSS\n");
VPrintf(1, "ThreadSanitizer: flushing memory due to RSS\n");
FlushShadowMemory();
rss = GetRSS();
if (flags()->verbosity > 0)
Printf("ThreadSanitizer: memory flushed RSS=%llu\n", (u64)rss>>20);
VPrintf(1, "ThreadSanitizer: memory flushed RSS=%llu\n", (u64)rss>>20);
}
last_rss = rss;
}
@ -303,7 +298,7 @@ void Initialize(ThreadState *thr) {
InitializeShadowMemory();
#endif
// Setup correct file descriptor for error reports.
__sanitizer_set_report_path(flags()->log_path);
__sanitizer_set_report_path(common_flags()->log_path);
InitializeSuppressions();
#ifndef TSAN_GO
InitializeLibIgnore();
@ -313,12 +308,11 @@ void Initialize(ThreadState *thr) {
#ifndef TSAN_GO
SetSandboxingCallback(StopBackgroundThread);
#endif
if (flags()->detect_deadlocks)
if (common_flags()->detect_deadlocks)
ctx->dd = DDetector::Create(flags());
if (ctx->flags.verbosity)
Printf("***** Running under ThreadSanitizer v2 (pid %d) *****\n",
(int)internal_getpid());
VPrintf(1, "***** Running under ThreadSanitizer v2 (pid %d) *****\n",
(int)internal_getpid());
// Initialize thread 0.
int tid = ThreadCreate(thr, 0, 0, true);
@ -349,7 +343,7 @@ int Finalize(ThreadState *thr) {
ctx->report_mtx.Unlock();
#ifndef TSAN_GO
if (ctx->flags.verbosity)
if (common_flags()->verbosity)
AllocatorPrintStats();
#endif
@ -370,7 +364,7 @@ int Finalize(ThreadState *thr) {
ctx->nmissed_expected);
}
if (flags()->print_suppressions)
if (common_flags()->print_suppressions)
PrintMatchedSuppressions();
#ifndef TSAN_GO
if (flags()->print_benign)

View File

@ -103,7 +103,7 @@ void MutexDestroy(ThreadState *thr, uptr pc, uptr addr) {
SyncVar *s = ctx->metamap.GetIfExistsAndLock(addr);
if (s == 0)
return;
if (flags()->detect_deadlocks) {
if (common_flags()->detect_deadlocks) {
Callback cb(thr, pc);
ctx->dd->MutexDestroy(&cb, &s->dd);
ctx->dd->MutexInit(&cb, &s->dd);
@ -172,7 +172,7 @@ void MutexLock(ThreadState *thr, uptr pc, uptr addr, int rec, bool try_lock) {
}
s->recursion += rec;
thr->mset.Add(s->GetId(), true, thr->fast_state.epoch());
if (flags()->detect_deadlocks && (s->recursion - rec) == 0) {
if (common_flags()->detect_deadlocks && (s->recursion - rec) == 0) {
Callback cb(thr, pc);
if (!try_lock)
ctx->dd->MutexBeforeLock(&cb, &s->dd, true);
@ -183,7 +183,7 @@ void MutexLock(ThreadState *thr, uptr pc, uptr addr, int rec, bool try_lock) {
// Can't touch s after this point.
if (report_double_lock)
ReportMutexMisuse(thr, pc, ReportTypeMutexDoubleLock, addr, mid);
if (flags()->detect_deadlocks) {
if (common_flags()->detect_deadlocks) {
Callback cb(thr, pc);
ReportDeadlock(thr, pc, ctx->dd->GetReport(&cb));
}
@ -215,7 +215,8 @@ int MutexUnlock(ThreadState *thr, uptr pc, uptr addr, bool all) {
}
}
thr->mset.Del(s->GetId(), true);
if (flags()->detect_deadlocks && s->recursion == 0 && !report_bad_unlock) {
if (common_flags()->detect_deadlocks && s->recursion == 0 &&
!report_bad_unlock) {
Callback cb(thr, pc);
ctx->dd->MutexBeforeUnlock(&cb, &s->dd, true);
}
@ -224,7 +225,7 @@ int MutexUnlock(ThreadState *thr, uptr pc, uptr addr, bool all) {
// Can't touch s after this point.
if (report_bad_unlock)
ReportMutexMisuse(thr, pc, ReportTypeMutexBadUnlock, addr, mid);
if (flags()->detect_deadlocks && !report_bad_unlock) {
if (common_flags()->detect_deadlocks && !report_bad_unlock) {
Callback cb(thr, pc);
ReportDeadlock(thr, pc, ctx->dd->GetReport(&cb));
}
@ -249,7 +250,7 @@ void MutexReadLock(ThreadState *thr, uptr pc, uptr addr, bool trylock) {
AcquireImpl(thr, pc, &s->clock);
s->last_lock = thr->fast_state.raw();
thr->mset.Add(s->GetId(), false, thr->fast_state.epoch());
if (flags()->detect_deadlocks && s->recursion == 0) {
if (common_flags()->detect_deadlocks && s->recursion == 0) {
Callback cb(thr, pc);
if (!trylock)
ctx->dd->MutexBeforeLock(&cb, &s->dd, false);
@ -260,7 +261,7 @@ void MutexReadLock(ThreadState *thr, uptr pc, uptr addr, bool trylock) {
// Can't touch s after this point.
if (report_bad_lock)
ReportMutexMisuse(thr, pc, ReportTypeMutexBadReadLock, addr, mid);
if (flags()->detect_deadlocks) {
if (common_flags()->detect_deadlocks) {
Callback cb(thr, pc);
ReportDeadlock(thr, pc, ctx->dd->GetReport(&cb));
}
@ -282,7 +283,7 @@ void MutexReadUnlock(ThreadState *thr, uptr pc, uptr addr) {
}
}
ReleaseImpl(thr, pc, &s->read_clock);
if (flags()->detect_deadlocks && s->recursion == 0) {
if (common_flags()->detect_deadlocks && s->recursion == 0) {
Callback cb(thr, pc);
ctx->dd->MutexBeforeUnlock(&cb, &s->dd, false);
}
@ -292,7 +293,7 @@ void MutexReadUnlock(ThreadState *thr, uptr pc, uptr addr) {
thr->mset.Del(mid, false);
if (report_bad_unlock)
ReportMutexMisuse(thr, pc, ReportTypeMutexBadReadUnlock, addr, mid);
if (flags()->detect_deadlocks) {
if (common_flags()->detect_deadlocks) {
Callback cb(thr, pc);
ReportDeadlock(thr, pc, ctx->dd->GetReport(&cb));
}
@ -330,7 +331,7 @@ void MutexReadOrWriteUnlock(ThreadState *thr, uptr pc, uptr addr) {
report_bad_unlock = true;
}
thr->mset.Del(s->GetId(), write);
if (flags()->detect_deadlocks && s->recursion == 0) {
if (common_flags()->detect_deadlocks && s->recursion == 0) {
Callback cb(thr, pc);
ctx->dd->MutexBeforeUnlock(&cb, &s->dd, write);
}
@ -339,7 +340,7 @@ void MutexReadOrWriteUnlock(ThreadState *thr, uptr pc, uptr addr) {
// Can't touch s after this point.
if (report_bad_unlock)
ReportMutexMisuse(thr, pc, ReportTypeMutexBadUnlock, addr, mid);
if (flags()->detect_deadlocks) {
if (common_flags()->detect_deadlocks) {
Callback cb(thr, pc);
ReportDeadlock(thr, pc, ctx->dd->GetReport(&cb));
}

View File

@ -61,7 +61,7 @@ static void StackStripMain(ReportStack *stack) {
ReportStack *last_frame2 = 0;
const char *prefix = "__interceptor_";
uptr prefix_len = internal_strlen(prefix);
const char *path_prefix = flags()->strip_path_prefix;
const char *path_prefix = common_flags()->strip_path_prefix;
uptr path_prefix_len = internal_strlen(path_prefix);
char *pos;
for (ReportStack *ent = stack; ent; ent = ent->next) {

View File

@ -107,7 +107,7 @@ void ThreadContext::OnStarted(void *arg) {
#ifndef TSAN_GO
AllocatorThreadStart(thr);
#endif
if (flags()->detect_deadlocks) {
if (common_flags()->detect_deadlocks) {
thr->dd_pt = ctx->dd->CreatePhysicalThread();
thr->dd_lt = ctx->dd->CreateLogicalThread(unique_id);
}
@ -134,7 +134,7 @@ void ThreadContext::OnFinished() {
}
epoch1 = thr->fast_state.epoch();
if (flags()->detect_deadlocks) {
if (common_flags()->detect_deadlocks) {
ctx->dd->DestroyPhysicalThread(thr->dd_pt);
ctx->dd->DestroyLogicalThread(thr->dd_lt);
}

View File

@ -32,7 +32,7 @@ void SyncVar::Init(ThreadState *thr, uptr pc, uptr addr, u64 uid) {
creation_stack_id = 0;
if (kCppMode) // Go does not use them
creation_stack_id = CurrentStackId(thr, pc);
if (flags()->detect_deadlocks)
if (common_flags()->detect_deadlocks)
DDMutexInit(thr, pc, this);
}

View File

@ -45,8 +45,6 @@ static const char *options1 =
" report_signal_unsafe=0"
" report_atomic_races=0"
" force_seq_cst_atomics=0"
" suppressions=qwerty"
" print_suppressions=0"
" print_benign=0"
" exitcode=111"
" halt_on_error=0"
@ -60,22 +58,6 @@ static const char *options1 =
" history_size=5"
" io_sync=1"
" die_after_fork=true"
" symbolize=0"
" external_symbolizer_path=asdfgh"
" allow_addr2line=true"
" strip_path_prefix=zxcvb"
" fast_unwind_on_fatal=0"
" fast_unwind_on_malloc=0"
" handle_ioctl=0"
" malloc_context_size=777"
" log_path=aaa"
" verbosity=2"
" detect_leaks=0"
" leak_check_at_exit=0"
" allocator_may_return_null=0"
" print_summary=0"
" legacy_pthread_cond=0"
"";
static const char *options2 =
@ -89,8 +71,6 @@ static const char *options2 =
" report_signal_unsafe=true"
" report_atomic_races=true"
" force_seq_cst_atomics=true"
" suppressions=aaaaa"
" print_suppressions=true"
" print_benign=true"
" exitcode=222"
" halt_on_error=true"
@ -104,22 +84,6 @@ static const char *options2 =
" history_size=6"
" io_sync=2"
" die_after_fork=false"
" symbolize=true"
" external_symbolizer_path=cccccc"
" allow_addr2line=false"
" strip_path_prefix=ddddddd"
" fast_unwind_on_fatal=true"
" fast_unwind_on_malloc=true"
" handle_ioctl=true"
" malloc_context_size=567"
" log_path=eeeeeee"
" verbosity=0"
" detect_leaks=true"
" leak_check_at_exit=true"
" allocator_may_return_null=true"
" print_summary=true"
" legacy_pthread_cond=true"
"";
void VerifyOptions1(Flags *f) {
@ -133,8 +97,6 @@ void VerifyOptions1(Flags *f) {
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->suppressions, std::string("qwerty"));
EXPECT_EQ(f->print_suppressions, 0);
EXPECT_EQ(f->print_benign, 0);
EXPECT_EQ(f->exitcode, 111);
EXPECT_EQ(f->halt_on_error, 0);
@ -148,22 +110,6 @@ void VerifyOptions1(Flags *f) {
EXPECT_EQ(f->history_size, 5);
EXPECT_EQ(f->io_sync, 1);
EXPECT_EQ(f->die_after_fork, true);
EXPECT_EQ(f->symbolize, 0);
EXPECT_EQ(f->external_symbolizer_path, std::string("asdfgh"));
EXPECT_EQ(f->allow_addr2line, true);
EXPECT_EQ(f->strip_path_prefix, std::string("zxcvb"));
EXPECT_EQ(f->fast_unwind_on_fatal, 0);
EXPECT_EQ(f->fast_unwind_on_malloc, 0);
EXPECT_EQ(f->handle_ioctl, 0);
EXPECT_EQ(f->malloc_context_size, 777);
EXPECT_EQ(f->log_path, std::string("aaa"));
EXPECT_EQ(f->verbosity, 2);
EXPECT_EQ(f->detect_leaks, 0);
EXPECT_EQ(f->leak_check_at_exit, 0);
EXPECT_EQ(f->allocator_may_return_null, 0);
EXPECT_EQ(f->print_summary, 0);
EXPECT_EQ(f->legacy_pthread_cond, false);
}
void VerifyOptions2(Flags *f) {
@ -177,8 +123,6 @@ void VerifyOptions2(Flags *f) {
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->suppressions, std::string("aaaaa"));
EXPECT_EQ(f->print_suppressions, true);
EXPECT_EQ(f->print_benign, true);
EXPECT_EQ(f->exitcode, 222);
EXPECT_EQ(f->halt_on_error, true);
@ -192,22 +136,6 @@ void VerifyOptions2(Flags *f) {
EXPECT_EQ(f->history_size, 6);
EXPECT_EQ(f->io_sync, 2);
EXPECT_EQ(f->die_after_fork, false);
EXPECT_EQ(f->symbolize, true);
EXPECT_EQ(f->external_symbolizer_path, std::string("cccccc"));
EXPECT_EQ(f->allow_addr2line, false);
EXPECT_EQ(f->strip_path_prefix, std::string("ddddddd"));
EXPECT_EQ(f->fast_unwind_on_fatal, true);
EXPECT_EQ(f->fast_unwind_on_malloc, true);
EXPECT_EQ(f->handle_ioctl, true);
EXPECT_EQ(f->malloc_context_size, 567);
EXPECT_EQ(f->log_path, std::string("eeeeeee"));
EXPECT_EQ(f->verbosity, 0);
EXPECT_EQ(f->detect_leaks, true);
EXPECT_EQ(f->leak_check_at_exit, true);
EXPECT_EQ(f->allocator_may_return_null, true);
EXPECT_EQ(f->print_summary, true);
EXPECT_EQ(f->legacy_pthread_cond, true);
}
static const char *test_default_options;