diff options
Diffstat (limited to 'compiler-rt')
| -rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_platform.h | 3 | ||||
| -rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_platform_linux.cc | 29 | ||||
| -rw-r--r-- | compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cc | 6 |
3 files changed, 37 insertions, 1 deletions
diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform.h b/compiler-rt/lib/tsan/rtl/tsan_platform.h index 888daf6bf6d..b80b268de43 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_platform.h +++ b/compiler-rt/lib/tsan/rtl/tsan_platform.h @@ -86,6 +86,9 @@ void FinalizePlatform(); void internal_start_thread(void(*func)(void*), void *arg); +// Says whether the addr relates to a global var. +// Guesses with high probability, may yield both false positives and negatives. +bool IsGlobalVar(uptr addr); uptr GetTlsSize(); void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size, uptr *tls_addr, uptr *tls_size); diff --git a/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cc b/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cc index f6b55982db8..9d4c2487315 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_platform_linux.cc @@ -132,6 +132,10 @@ void InitializeShadowMemory() { DPrintf("stack %zx\n", (uptr)&shadow); } +static uptr g_tls_size; +static uptr g_data_start; +static uptr g_data_end; + #ifndef TSAN_GO static void CheckPIE() { // Ensure that the binary is indeed compiled with -pie. @@ -150,7 +154,26 @@ static void CheckPIE() { } } -static uptr g_tls_size; +static void InitDataSeg() { + MemoryMappingLayout proc_maps; + uptr start, end, offset; + char name[128]; + bool prev_is_data = false; + while (proc_maps.Next(&start, &end, &offset, name, ARRAY_SIZE(name))) { + DPrintf("%p-%p %p %s\n", start, end, offset, name); + bool is_data = offset != 0 && name[0] != 0; + bool is_bss = offset == 0 && name[0] == 0 && prev_is_data; + if (g_data_start == 0 && is_data) + g_data_start = start; + if (is_bss) + g_data_end = end; + prev_is_data = is_data; + } + DPrintf("guessed data_start=%p data_end=%p\n", g_data_start, g_data_end); + CHECK_LT(g_data_start, g_data_end); + CHECK_GE((uptr)&g_data_start, g_data_start); + CHECK_LT((uptr)&g_data_start, g_data_end); +} #ifdef __i386__ # define INTERNAL_FUNCTION __attribute__((regparm(3), stdcall)) @@ -187,6 +210,7 @@ const char *InitializePlatform() { #ifndef TSAN_GO CheckPIE(); g_tls_size = (uptr)InitTlsSize(); + InitDataSeg(); #endif return getenv("TSAN_OPTIONS"); } @@ -232,6 +256,9 @@ void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size, #endif } +bool IsGlobalVar(uptr addr) { + return g_data_start && addr >= g_data_start && addr < g_data_end; +} } // namespace __tsan diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cc b/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cc index 45dc5591d90..3175f91ece8 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cc @@ -40,6 +40,12 @@ void MutexDestroy(ThreadState *thr, uptr pc, uptr addr) { CHECK_GT(thr->in_rtl, 0); DPrintf("#%d: MutexDestroy %zx\n", thr->tid, addr); StatInc(thr, StatMutexDestroy); +#ifndef TSAN_GO + // Global mutexes not marked as LINKER_INITIALIZED + // cause tons of not interesting reports, so just ignore it. + if (IsGlobalVar(addr)) + return; +#endif SyncVar *s = ctx->synctab.GetAndRemove(thr, pc, addr); if (s == 0) return; |

