[llvm-commits] [compiler-rt] r168786 - in /compiler-rt/trunk/lib: sanitizer_common/sanitizer_posix.cc tsan/rtl/tsan_flags.cc tsan/rtl/tsan_flags.h tsan/rtl/tsan_platform_linux.cc tsan/rtl/tsan_rtl.cc tsan/rtl/tsan_rtl.h tsan/rtl/tsan_rtl_report.cc tsan/rtl/tsan_rtl_thread.cc tsan/rtl/tsan_trace.h tsan/tests/unit/tsan_shadow_test.cc
Dmitry Vyukov
dvyukov at google.com
Wed Nov 28 05:02:29 PST 2012
Done in r168789. Thanks!
On Wed, Nov 28, 2012 at 4:38 PM, Kostya Serebryany <kcc at google.com> wrote:
> Excellent.
> Minor comment below.
>
> On Wed, Nov 28, 2012 at 4:19 PM, Dmitry Vyukov <dvyukov at google.com> wrote:
>>
>> Author: dvyukov
>> Date: Wed Nov 28 06:19:50 2012
>> New Revision: 168786
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=168786&view=rev
>> Log:
>> tsan: dynamic history size
>> introduces history_size parameter that can be used to control trace size
>> at startup
>>
>> Modified:
>> compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc
>> compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc
>> compiler-rt/trunk/lib/tsan/rtl/tsan_flags.h
>> compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc
>> compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc
>> compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h
>> compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc
>> compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc
>> compiler-rt/trunk/lib/tsan/rtl/tsan_trace.h
>> compiler-rt/trunk/lib/tsan/tests/unit/tsan_shadow_test.cc
>>
>> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc
>> URL:
>> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc?rev=168786&r1=168785&r2=168786&view=diff
>>
>> ==============================================================================
>> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc (original)
>> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc Wed Nov 28
>> 06:19:50 2012
>> @@ -169,7 +169,10 @@
>> struct rlimit rlim;
>> rlim.rlim_cur = limit;
>> rlim.rlim_max = limit;
>> - CHECK_EQ(0, setrlimit(RLIMIT_STACK, &rlim));
>> + if (setrlimit(RLIMIT_STACK, &rlim)) {
>> + Report("setrlimit() failed %d\n", errno);
>> + Die();
>> + }
>> CHECK(!StackSizeIsUnlimited());
>> }
>>
>>
>> Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc
>> URL:
>> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc?rev=168786&r1=168785&r2=168786&view=diff
>>
>> ==============================================================================
>> --- compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc (original)
>> +++ compiler-rt/trunk/lib/tsan/rtl/tsan_flags.cc Wed Nov 28 06:19:50 2012
>> @@ -56,6 +56,11 @@
>> f->stop_on_start = false;
>> f->running_on_valgrind = false;
>> f->external_symbolizer_path = "";
>> + f->history_size = 2;
>> +
>> +#ifdef TSAN_GO
>
>
> For such checks I'd prefer to have if (TSAN_GO) instead of #ifdef TSAN_GO.
> (here and in other places).
>
>
>>
>> + f->history_size = 1; // There are a lot of goroutines.
>> +#endif
>>
>> // Let a frontend override.
>> OverrideFlags(f);
>> @@ -79,12 +84,19 @@
>> ParseFlag(env, &f->flush_memory_ms, "flush_memory_ms");
>> ParseFlag(env, &f->stop_on_start, "stop_on_start");
>> ParseFlag(env, &f->external_symbolizer_path,
>> "external_symbolizer_path");
>> + ParseFlag(env, &f->history_size, "history_size");
>>
>> if (!f->report_bugs) {
>> f->report_thread_leaks = false;
>> f->report_destroy_locked = false;
>> f->report_signal_unsafe = false;
>> }
>> +
>> + if (f->history_size < 0 || f->history_size > 7) {
>> + Printf("ThreadSanitizer: incorrect value for history_size"
>> + " (must be [0..7])\n");
>> + Die();
>> + }
>> }
>>
>> } // namespace __tsan
>>
>> Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_flags.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_flags.h?rev=168786&r1=168785&r2=168786&view=diff
>>
>> ==============================================================================
>> --- compiler-rt/trunk/lib/tsan/rtl/tsan_flags.h (original)
>> +++ compiler-rt/trunk/lib/tsan/rtl/tsan_flags.h Wed Nov 28 06:19:50 2012
>> @@ -66,6 +66,12 @@
>> bool running_on_valgrind;
>> // Path to external symbolizer.
>> const char *external_symbolizer_path;
>> + // Per-thread history size, controls how many previous memory accesses
>> + // is remembered per thread. Possible values are [0..7].
>
> are remembered
>
>>
>> + // history_size=0 amounts to 32K memory accesses. Each next value
>> doubles
>> + // the amount of memory accesses, up to history_size=7 that amounts to
>> + // 4M memory accesses. The default value is 2 (128K memory accesses).
>> + int history_size;
>> };
>>
>> Flags *flags();
>>
>> Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc
>> URL:
>> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc?rev=168786&r1=168785&r2=168786&view=diff
>>
>> ==============================================================================
>> --- compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc (original)
>> +++ compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc Wed Nov 28
>> 06:19:50 2012
>> @@ -202,28 +202,50 @@
>> }
>> #endif // #ifndef TSAN_GO
>>
>> +static rlim_t getlim(int res) {
>> + rlimit rlim;
>> + CHECK_EQ(0, getrlimit(res, &rlim));
>> + return rlim.rlim_cur;
>> +}
>> +
>> +static void setlim(int res, rlim_t lim) {
>> + // The following magic is to prevent clang from replacing it with
>> memset.
>> + volatile rlimit rlim;
>> + rlim.rlim_cur = lim;
>> + rlim.rlim_max = lim;
>> + setrlimit(res, (rlimit*)&rlim);
>> +}
>> +
>> const char *InitializePlatform() {
>> void *p = 0;
>> if (sizeof(p) == 8) {
>> // Disable core dumps, dumping of 16TB usually takes a bit long.
>> - // The following magic is to prevent clang from replacing it with
>> memset.
>> - volatile rlimit lim;
>> - lim.rlim_cur = 0;
>> - lim.rlim_max = 0;
>> - setrlimit(RLIMIT_CORE, (rlimit*)&lim);
>> + setlim(RLIMIT_CORE, 0);
>> }
>> + bool reexec = false;
>> // TSan doesn't play well with unlimited stack size (as stack
>> // overlaps with shadow memory). If we detect unlimited stack size,
>> // we re-exec the program with limited stack size as a best effort.
>> - if (StackSizeIsUnlimited()) {
>> - const uptr kMaxStackSize = 32 * 1024 * 1024; // 32 Mb
>> + if (getlim(RLIMIT_STACK) == (rlim_t)-1) {
>> + const uptr kMaxStackSize = 32 * 1024 * 1024;
>> Report("WARNING: Program is run with unlimited stack size, which "
>> "wouldn't work with ThreadSanitizer.\n");
>> Report("Re-execing with stack size limited to %zd bytes.\n",
>> kMaxStackSize);
>> SetStackSizeLimitInBytes(kMaxStackSize);
>> - ReExec();
>> + reexec = true;
>> }
>>
>> + if (getlim(RLIMIT_AS) != (rlim_t)-1) {
>> + Report("WARNING: Program is run with limited virtual address space,
>> which "
>> + "wouldn't work with ThreadSanitizer.\n");
>> + Report("Re-execing with unlimited virtual address space.\n");
>> + setlim(RLIMIT_AS, -1);
>> + reexec = true;
>> + }
>> +
>> + if (reexec)
>> + ReExec();
>> +
>> #ifndef TSAN_GO
>> CheckPIE();
>> g_tls_size = (uptr)InitTlsSize();
>>
>> Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc
>> URL:
>> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc?rev=168786&r1=168785&r2=168786&view=diff
>>
>> ==============================================================================
>> --- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc (original)
>> +++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.cc Wed Nov 28 06:19:50 2012
>> @@ -290,11 +290,14 @@
>>
>> uptr TraceTopPC(ThreadState *thr) {
>> Event *events = (Event*)GetThreadTrace(thr->tid);
>> - uptr pc = events[thr->fast_state.epoch() % kTraceSize]
>> - & ((1ull << 61) - 1);
>> + uptr pc = events[thr->fast_state.GetTracePos()];
>> return pc;
>> }
>>
>> +uptr TraceSize() {
>> + return (uptr)(1ull << (kTracePartSizeBits + flags()->history_size +
>> 1));
>> +}
>> +
>> #ifndef TSAN_GO
>> extern "C" void __tsan_trace_switch() {
>> TraceSwitch(cur_thread());
>>
>> Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h?rev=168786&r1=168785&r2=168786&view=diff
>>
>> ==============================================================================
>> --- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h (original)
>> +++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl.h Wed Nov 28 06:19:50 2012
>> @@ -74,6 +74,7 @@
>> // tid : kTidBits
>> // epoch : kClkBits
>> // unused : -
>> +// history_size : 3
>> class FastState {
>> public:
>> FastState(u64 tid, u64 epoch) {
>> @@ -113,6 +114,27 @@
>> void ClearIgnoreBit() { x_ &= ~kIgnoreBit; }
>> bool GetIgnoreBit() const { return (s64)x_ < 0; }
>>
>> + void SetHistorySize(int hs) {
>> + CHECK_GE(hs, 0);
>> + CHECK_LE(hs, 7);
>> + x_ = (x_ & ~7) | hs;
>> + }
>> +
>> + int GetHistorySize() const {
>> + return (int)(x_ & 7);
>> + }
>> +
>> + void ClearHistorySize() {
>> + x_ &= ~7;
>> + }
>> +
>> + u64 GetTracePos() const {
>> + const int hs = GetHistorySize();
>> + // When hs == 0, the trace consists of 2 parts.
>>
>> + const u64 mask = (1ull << (kTracePartSizeBits + hs + 1)) - 1;
>> + return epoch() & mask;
>> + }
>> +
>> private:
>> friend class Shadow;
>> static const int kTidShift = 64 - kTidBits - 1;
>> @@ -131,9 +153,14 @@
>> // addr0 : 3
>> class Shadow : public FastState {
>> public:
>> - explicit Shadow(u64 x) : FastState(x) { }
>> + explicit Shadow(u64 x)
>> + : FastState(x) {
>> + }
>>
>> - explicit Shadow(const FastState &s) : FastState(s.x_) { }
>> + explicit Shadow(const FastState &s)
>> + : FastState(s.x_) {
>> + ClearHistorySize();
>> + }
>>
>> void SetAddr0AndSizeLog(u64 addr0, unsigned kAccessSizeLog) {
>> DCHECK_EQ(x_ & 31, 0);
>> @@ -535,12 +562,13 @@
>>
>> void TraceSwitch(ThreadState *thr);
>> uptr TraceTopPC(ThreadState *thr);
>> +uptr TraceSize();
>>
>> extern "C" void __tsan_trace_switch();
>> void ALWAYS_INLINE INLINE TraceAddEvent(ThreadState *thr, FastState fs,
>> EventType typ, uptr addr) {
>> StatInc(thr, StatEvents);
>> - u64 epoch = fs.epoch();
>> + u64 epoch = fs.GetTracePos();
>
>
> Should this be named epoch then?
>
>>
>> if (UNLIKELY((epoch % kTracePartSize) == 0)) {
>> #ifndef TSAN_GO
>> HACKY_CALL(__tsan_trace_switch);
>> @@ -549,7 +577,7 @@
>> #endif
>> }
>> Event *trace = (Event*)GetThreadTrace(fs.tid());
>> - Event *evp = &trace[epoch % kTraceSize];
>> + Event *evp = &trace[epoch];
>> Event ev = (u64)addr | ((u64)typ << 61);
>> *evp = ev;
>> }
>>
>> Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc
>> URL:
>> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc?rev=168786&r1=168785&r2=168786&view=diff
>>
>> ==============================================================================
>> --- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc (original)
>> +++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_report.cc Wed Nov 28 06:19:50
>> 2012
>> @@ -263,11 +263,11 @@
>> return;
>> }
>> Lock l(&trace->mtx);
>> - const int partidx = (epoch / (kTraceSize / kTraceParts)) % kTraceParts;
>> + const int partidx = (epoch / (TraceSize() / kTraceParts)) %
>> kTraceParts;
>> TraceHeader* hdr = &trace->headers[partidx];
>> if (epoch < hdr->epoch0)
>> return;
>> - const u64 eend = epoch % kTraceSize;
>> + const u64 eend = epoch % TraceSize();
>> const u64 ebegin = eend / kTracePartSize * kTracePartSize;
>> DPrintf("#%d: RestoreStack epoch=%zu ebegin=%zu eend=%zu partidx=%d\n",
>> tid, (uptr)epoch, (uptr)ebegin, (uptr)eend, partidx);
>>
>> Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc
>> URL:
>> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc?rev=168786&r1=168785&r2=168786&view=diff
>>
>> ==============================================================================
>> --- compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc (original)
>> +++ compiler-rt/trunk/lib/tsan/rtl/tsan_rtl_thread.cc Wed Nov 28 06:19:50
>> 2012
>> @@ -123,7 +123,7 @@
>> void *mem = internal_alloc(MBlockThreadContex,
>> sizeof(ThreadContext));
>> tctx = new(mem) ThreadContext(tid);
>> ctx->threads[tid] = tctx;
>> - MapThreadTrace(GetThreadTrace(tid), kTraceSize * sizeof(Event));
>> + MapThreadTrace(GetThreadTrace(tid), TraceSize() * sizeof(Event));
>> }
>> CHECK_NE(tctx, 0);
>> CHECK_GE(tid, 0);
>> @@ -149,7 +149,6 @@
>> thr->fast_synch_epoch = thr->fast_state.epoch();
>> thr->clock.release(&tctx->sync);
>> StatInc(thr, StatSyncRelease);
>> -
>> tctx->creation_stack.ObtainCurrent(thr, pc);
>> }
>> return tid;
>> @@ -205,6 +204,7 @@
>> thr->fast_synch_epoch = tctx->epoch0;
>> thr->clock.set(tid, tctx->epoch0);
>> thr->clock.acquire(&tctx->sync);
>> + thr->fast_state.SetHistorySize(flags()->history_size);
>> StatInc(thr, StatSyncAcquire);
>> DPrintf("#%d: ThreadStart epoch=%zu stk_addr=%zx stk_size=%zx "
>> "tls_addr=%zx tls_size=%zx\n",
>>
>> Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_trace.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_trace.h?rev=168786&r1=168785&r2=168786&view=diff
>>
>> ==============================================================================
>> --- compiler-rt/trunk/lib/tsan/rtl/tsan_trace.h (original)
>> +++ compiler-rt/trunk/lib/tsan/rtl/tsan_trace.h Wed Nov 28 06:19:50 2012
>> @@ -19,12 +19,9 @@
>>
>> namespace __tsan {
>>
>> -#ifndef TSAN_HISTORY_SIZE // in kibitraces
>> -#define TSAN_HISTORY_SIZE 128
>> -#endif
>> -
>> -const int kTracePartSize = 16 * 1024;
>> -const int kTraceParts = TSAN_HISTORY_SIZE * 1024 / kTracePartSize;
>> +const int kTracePartSizeBits = 14;
>> +const int kTracePartSize = 1 << kTracePartSizeBits;
>> +const int kTraceParts = 4 * 1024 * 1024 / kTracePartSize;
>> const int kTraceSize = kTracePartSize * kTraceParts;
>>
>> // Must fit into 3 bits.
>>
>> Modified: compiler-rt/trunk/lib/tsan/tests/unit/tsan_shadow_test.cc
>> URL:
>> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/tests/unit/tsan_shadow_test.cc?rev=168786&r1=168785&r2=168786&view=diff
>>
>> ==============================================================================
>> --- compiler-rt/trunk/lib/tsan/tests/unit/tsan_shadow_test.cc (original)
>> +++ compiler-rt/trunk/lib/tsan/tests/unit/tsan_shadow_test.cc Wed Nov 28
>> 06:19:50 2012
>> @@ -22,6 +22,7 @@
>> EXPECT_EQ(s.epoch(), (u64)22);
>> EXPECT_EQ(s.GetIgnoreBit(), false);
>> EXPECT_EQ(s.GetFreedAndReset(), false);
>> + EXPECT_EQ(s.GetHistorySize(), 0);
>> EXPECT_EQ(s.addr0(), (u64)0);
>> EXPECT_EQ(s.size(), (u64)1);
>> EXPECT_EQ(s.is_write(), false);
>> @@ -35,6 +36,14 @@
>> EXPECT_EQ(s.GetIgnoreBit(), true);
>> s.ClearIgnoreBit();
>> EXPECT_EQ(s.GetIgnoreBit(), false);
>> +
>> + for (int i = 0; i < 8; i++) {
>> + s.SetHistorySize(i);
>> + EXPECT_EQ(s.GetHistorySize(), i);
>> + }
>> + s.SetHistorySize(2);
>> + s.ClearHistorySize();
>> + EXPECT_EQ(s.GetHistorySize(), 0);
>> }
>>
>> TEST(Shadow, Mapping) {
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
>
More information about the llvm-commits
mailing list