summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2012-11-06 16:00:16 +0000
committerDmitry Vyukov <dvyukov@google.com>2012-11-06 16:00:16 +0000
commita05fcc1e3e045097f2f1a20798cbe038bbb1d6a9 (patch)
treea462b98e33571277b0ea0f576fefdb144510affe
parentbe1a4c4be86f7960dbeb7b44d3b13ce5b9b13b4e (diff)
downloadcompiler-rt-a05fcc1e3e045097f2f1a20798cbe038bbb1d6a9.tar.gz
tsan: lazily allocate shadow for Go
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@167464 91177308-0d34-0410-b5e6-96231b3b80d8
-rwxr-xr-xlib/tsan/go/buildgo.sh7
-rw-r--r--lib/tsan/go/test.c2
-rw-r--r--lib/tsan/go/tsan_go.cc4
-rw-r--r--lib/tsan/rtl/tsan_defs.h3
-rw-r--r--lib/tsan/rtl/tsan_platform_linux.cc8
-rw-r--r--lib/tsan/rtl/tsan_platform_mac.cc2
-rw-r--r--lib/tsan/rtl/tsan_platform_windows.cc24
-rw-r--r--lib/tsan/rtl/tsan_rtl.cc14
-rw-r--r--lib/tsan/rtl/tsan_rtl.h1
9 files changed, 32 insertions, 33 deletions
diff --git a/lib/tsan/go/buildgo.sh b/lib/tsan/go/buildgo.sh
index e7e27c8a6..86f468a44 100755
--- a/lib/tsan/go/buildgo.sh
+++ b/lib/tsan/go/buildgo.sh
@@ -1,5 +1,6 @@
#!/bin/bash
set -e
+set -x
SRCS="
tsan_go.cc
@@ -25,7 +26,7 @@ SRCS="
if [ "`uname -a | grep Linux`" != "" ]; then
SUFFIX="linux_amd64"
OSCFLAGS="-fPIC -ffreestanding"
- OSLDFLAGS="-lpthread"
+ OSLDFLAGS="-lpthread -fPIC -fpie"
SRCS+="
../rtl/tsan_platform_linux.cc
../../sanitizer_common/sanitizer_posix.cc
@@ -34,7 +35,7 @@ if [ "`uname -a | grep Linux`" != "" ]; then
elif [ "`uname -a | grep Darwin`" != "" ]; then
SUFFIX="darwin_amd64"
OSCFLAGS="-fPIC"
- OSLDFLAGS="-lpthread"
+ OSLDFLAGS="-lpthread -fPIC -fpie"
SRCS+="
../rtl/tsan_platform_mac.cc
../../sanitizer_common/sanitizer_posix.cc
@@ -74,4 +75,4 @@ echo as gotsan.s -o race_$SUFFIX.syso
as gotsan.s -o race_$SUFFIX.syso
gcc test.c race_$SUFFIX.syso -m64 -o test $OSLDFLAGS
-TSAN_OPTIONS="exitcode=0" ./test
+TSAN_OPTIONS="exitcode=0 atexit_sleep_ms=0" ./test
diff --git a/lib/tsan/go/test.c b/lib/tsan/go/test.c
index a9a5b3dbf..865da4ef0 100644
--- a/lib/tsan/go/test.c
+++ b/lib/tsan/go/test.c
@@ -15,6 +15,7 @@
void __tsan_init();
void __tsan_fini();
+void __tsan_map_shadow(void *addr, unsigned long size);
void __tsan_go_start(int pgoid, int chgoid, void *pc);
void __tsan_go_end(int goid);
void __tsan_read(int goid, void *addr, void *pc);
@@ -35,6 +36,7 @@ char buf[10];
int main(void) {
__tsan_init();
+ __tsan_map_shadow((unsigned long)buf & ~(4096-1), 4096);
__tsan_func_enter(0, &main);
__tsan_malloc(0, buf, 10, 0);
__tsan_release(0, buf);
diff --git a/lib/tsan/go/tsan_go.cc b/lib/tsan/go/tsan_go.cc
index ccedc64cd..a7e8d9677 100644
--- a/lib/tsan/go/tsan_go.cc
+++ b/lib/tsan/go/tsan_go.cc
@@ -108,6 +108,10 @@ void __tsan_fini() {
exit(res);
}
+void __tsan_map_shadow(uptr addr, uptr size) {
+ MapShadow(addr, size);
+}
+
void __tsan_read(int goid, void *addr, void *pc) {
ThreadState *thr = goroutines[goid];
MemoryAccess(thr, (uptr)pc, (uptr)addr, 0, false);
diff --git a/lib/tsan/rtl/tsan_defs.h b/lib/tsan/rtl/tsan_defs.h
index 595aff32a..52862bc36 100644
--- a/lib/tsan/rtl/tsan_defs.h
+++ b/lib/tsan/rtl/tsan_defs.h
@@ -51,6 +51,9 @@ const uptr kShadowCell = 8;
// Size of a single shadow value (u64).
const uptr kShadowSize = 8;
+// Shadow memory is kShadowMultiplier times larger than user memory.
+const uptr kShadowMultiplier = kShadowSize * kShadowCnt / kShadowCell;
+
#if defined(TSAN_COLLECT_STATS) && TSAN_COLLECT_STATS
const bool kCollectStats = true;
#else
diff --git a/lib/tsan/rtl/tsan_platform_linux.cc b/lib/tsan/rtl/tsan_platform_linux.cc
index 5cb3006ce..3ddfb7f76 100644
--- a/lib/tsan/rtl/tsan_platform_linux.cc
+++ b/lib/tsan/rtl/tsan_platform_linux.cc
@@ -90,6 +90,7 @@ static void ProtectRange(uptr beg, uptr end) {
}
#endif
+#ifndef TSAN_GO
void InitializeShadowMemory() {
uptr shadow = (uptr)MmapFixedNoReserve(kLinuxShadowBeg,
kLinuxShadowEnd - kLinuxShadowBeg);
@@ -99,30 +100,25 @@ void InitializeShadowMemory() {
"to link with -pie (%p, %p).\n", shadow, kLinuxShadowBeg);
Die();
}
-#ifndef TSAN_GO
const uptr kClosedLowBeg = 0x200000;
const uptr kClosedLowEnd = kLinuxShadowBeg - 1;
const uptr kClosedMidBeg = kLinuxShadowEnd + 1;
const uptr kClosedMidEnd = kLinuxAppMemBeg - 1;
ProtectRange(kClosedLowBeg, kClosedLowEnd);
ProtectRange(kClosedMidBeg, kClosedMidEnd);
-#endif
-#ifndef TSAN_GO
DPrintf("kClosedLow %zx-%zx (%zuGB)\n",
kClosedLowBeg, kClosedLowEnd, (kClosedLowEnd - kClosedLowBeg) >> 30);
-#endif
DPrintf("kLinuxShadow %zx-%zx (%zuGB)\n",
kLinuxShadowBeg, kLinuxShadowEnd,
(kLinuxShadowEnd - kLinuxShadowBeg) >> 30);
-#ifndef TSAN_GO
DPrintf("kClosedMid %zx-%zx (%zuGB)\n",
kClosedMidBeg, kClosedMidEnd, (kClosedMidEnd - kClosedMidBeg) >> 30);
-#endif
DPrintf("kLinuxAppMem %zx-%zx (%zuGB)\n",
kLinuxAppMemBeg, kLinuxAppMemEnd,
(kLinuxAppMemEnd - kLinuxAppMemBeg) >> 30);
DPrintf("stack %zx\n", (uptr)&shadow);
}
+#endif
static uptr g_data_start;
static uptr g_data_end;
diff --git a/lib/tsan/rtl/tsan_platform_mac.cc b/lib/tsan/rtl/tsan_platform_mac.cc
index 069d27eb6..a8e0a56ae 100644
--- a/lib/tsan/rtl/tsan_platform_mac.cc
+++ b/lib/tsan/rtl/tsan_platform_mac.cc
@@ -52,6 +52,7 @@ uptr GetShadowMemoryConsumption() {
void FlushShadowMemory() {
}
+#ifndef TSAN_GO
void InitializeShadowMemory() {
uptr shadow = (uptr)MmapFixedNoReserve(kLinuxShadowBeg,
kLinuxShadowEnd - kLinuxShadowBeg);
@@ -68,6 +69,7 @@ void InitializeShadowMemory() {
kLinuxAppMemBeg, kLinuxAppMemEnd,
(kLinuxAppMemEnd - kLinuxAppMemBeg) >> 30);
}
+#endif
const char *InitializePlatform() {
void *p = 0;
diff --git a/lib/tsan/rtl/tsan_platform_windows.cc b/lib/tsan/rtl/tsan_platform_windows.cc
index 15745fb45..be515b9ec 100644
--- a/lib/tsan/rtl/tsan_platform_windows.cc
+++ b/lib/tsan/rtl/tsan_platform_windows.cc
@@ -33,30 +33,6 @@ uptr GetShadowMemoryConsumption() {
void FlushShadowMemory() {
}
-void InitializeShadowMemory() {
-/*
- uptr shadow = (uptr)MmapFixedNoReserve(kLinuxShadowBeg,
- kLinuxShadowEnd - kLinuxShadowBeg);
- if (shadow != kLinuxShadowBeg) {
- Printf("FATAL: ThreadSanitizer can not mmap the shadow memory\n");
- Printf("FATAL: Make sure to compile with -fPIE and "
- "to link with -pie.\n");
- Die();
- }
-*/
-
- MmapFixedNoReserve(MemToShadow(kLinuxAppMemBeg), (1ull<<20) * 16 * 4);
- MmapCommit(MemToShadow(kLinuxAppMemBeg), (1ull<<20) * 16 * 4);
- MmapFixedNoReserve(MemToShadow(0xf840000000ull), (1ull<<20) * 4096 * 4);
- MmapCommit(MemToShadow(0xf840000000ull), (1ull<<20) * 256 * 4);
- DPrintf("kLinuxShadow %zx-%zx (%zuGB)\n",
- kLinuxShadowBeg, kLinuxShadowEnd,
- (kLinuxShadowEnd - kLinuxShadowBeg) >> 30);
- DPrintf("kLinuxAppMem %zx-%zx (%zuGB)\n",
- kLinuxAppMemBeg, kLinuxAppMemEnd,
- (kLinuxAppMemEnd - kLinuxAppMemBeg) >> 30);
-}
-
const char *InitializePlatform() {
return getenv("TSAN_OPTIONS");
}
diff --git a/lib/tsan/rtl/tsan_rtl.cc b/lib/tsan/rtl/tsan_rtl.cc
index 7fa1e5514..f5b5d46e1 100644
--- a/lib/tsan/rtl/tsan_rtl.cc
+++ b/lib/tsan/rtl/tsan_rtl.cc
@@ -161,6 +161,18 @@ static void InitializeMemoryFlush() {
internal_start_thread(&MemoryFlushThread, 0);
}
+void MapShadow(uptr addr, uptr size) {
+ uptr saddr = MemToShadow(addr);
+ uptr ssize = size * kShadowMultiplier;
+ void *p = MmapFixedNoReserve(saddr, ssize);
+ if ((uptr)p != saddr) {
+ Printf("FATAL: ThreadSanitizer failed to mmap shadow memory"
+ " %p(%p) -> %p(%p) = %p\n",
+ addr, size, saddr, ssize, p);
+ Die();
+ }
+}
+
void Initialize(ThreadState *thr) {
// Thread safe because done before all threads exist.
static bool is_initialized = false;
@@ -179,7 +191,9 @@ void Initialize(ThreadState *thr) {
InitializeMutex();
InitializeDynamicAnnotations();
ctx = new(ctx_placeholder) Context;
+#ifndef TSAN_GO
InitializeShadowMemory();
+#endif
ctx->dead_list_size = 0;
ctx->dead_list_head = 0;
ctx->dead_list_tail = 0;
diff --git a/lib/tsan/rtl/tsan_rtl.h b/lib/tsan/rtl/tsan_rtl.h
index 16894b338..49388aa53 100644
--- a/lib/tsan/rtl/tsan_rtl.h
+++ b/lib/tsan/rtl/tsan_rtl.h
@@ -439,6 +439,7 @@ void ALWAYS_INLINE INLINE StatInc(ThreadState *thr, StatType typ, u64 n = 1) {
thr->stat[typ] += n;
}
+void MapShadow(uptr addr, uptr size);
void InitializeShadowMemory();
void InitializeInterceptors();
void InitializeDynamicAnnotations();