forked from OSchip/llvm-project
[TSan] Use common flags in the same way as all the other sanitizers
llvm-svn: 217559
This commit is contained in:
parent
611c906cb3
commit
5c825967ea
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue