diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp @@ -999,7 +999,6 @@ // Reset middle part. u64 *p1 = p; p = RoundDown(end, kPageSize); - UnmapOrDie((void*)p1, (uptr)p - (uptr)p1); if (!MmapFixedSuperNoReserve((uptr)p1, (uptr)p - (uptr)p1)) Die(); // Set the ending. diff --git a/compiler-rt/test/tsan/mmap_stress2.cpp b/compiler-rt/test/tsan/mmap_stress2.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/tsan/mmap_stress2.cpp @@ -0,0 +1,51 @@ +// RUN: %clang_tsan -O1 %s -o %t && %env_tsan_opts=report_atomic_races=0 %run %t 2>&1 | FileCheck %s +// This test exposed non-atomicity in mmap interceptor +// which made shadow for the region temporarily unmapped. +// This resulted in crashes in the Accesser thread. +#include "test.h" +#include +#include + +// The size needs to be large enough to trigger +// large region optimization in the runtime. +const size_t kMmapSize = 16 << 20; + +void *Remapper(void *arg) { + for (;;) { + void *p = mmap(arg, kMmapSize, PROT_READ | PROT_WRITE, + MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0); + if (p == MAP_FAILED) + exit(printf("mmap failed: %d\n", errno)); + } + return 0; +} + +void *Accesser(void *arg) { + unsigned rnd = time(0); + for (;;) { + int index = rand_r(&rnd) % kMmapSize; + char *p = &((char *)arg)[index]; + __atomic_fetch_add(p, 1, __ATOMIC_ACQ_REL); + } + return 0; +} + +int main() { + void *p = mmap(0, kMmapSize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0); + if (p == MAP_FAILED) + exit(printf("mmap failed: %d\n", errno)); + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_t th[2]; + if (pthread_create(&th[0], &attr, Remapper, p)) + exit(printf("pthread_create failed: %d\n", errno)); + if (pthread_create(&th[1], &attr, Accesser, p)) + exit(printf("pthread_create failed: %d\n", errno)); + pthread_attr_destroy(&attr); + sleep(3); + fprintf(stderr, "DONE\n"); +} + +// CHECK: DONE