[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
Kostya Serebryany
kcc at google.com
Wed Nov 28 04:38:54 PST 2012
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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20121128/0d4f826e/attachment.html>
More information about the llvm-commits
mailing list