summaryrefslogtreecommitdiff
path: root/lib/tsan/go
diff options
context:
space:
mode:
Diffstat (limited to 'lib/tsan/go')
-rwxr-xr-xlib/tsan/go/buildgo.sh5
-rw-r--r--lib/tsan/go/test.c46
-rw-r--r--lib/tsan/go/tsan_go.cc96
3 files changed, 69 insertions, 78 deletions
diff --git a/lib/tsan/go/buildgo.sh b/lib/tsan/go/buildgo.sh
index a153afd6ee8eb..51f1a7975b573 100755
--- a/lib/tsan/go/buildgo.sh
+++ b/lib/tsan/go/buildgo.sh
@@ -20,6 +20,7 @@ SRCS="
../../sanitizer_common/sanitizer_flags.cc
../../sanitizer_common/sanitizer_libc.cc
../../sanitizer_common/sanitizer_printf.cc
+ ../../sanitizer_common/sanitizer_thread_registry.cc
"
if [ "`uname -a | grep Linux`" != "" ]; then
@@ -29,7 +30,9 @@ if [ "`uname -a | grep Linux`" != "" ]; then
SRCS+="
../rtl/tsan_platform_linux.cc
../../sanitizer_common/sanitizer_posix.cc
+ ../../sanitizer_common/sanitizer_posix_libcdep.cc
../../sanitizer_common/sanitizer_linux.cc
+ ../../sanitizer_common/sanitizer_linux_libcdep.cc
"
elif [ "`uname -a | grep Darwin`" != "" ]; then
SUFFIX="darwin_amd64"
@@ -60,7 +63,7 @@ for F in $SRCS; do
cat $F >> gotsan.cc
done
-FLAGS=" -I../rtl -I../.. -I../../sanitizer_common -I../../../include -m64 -Wall -Werror -fno-exceptions -DTSAN_GO -DSANITIZER_GO -DTSAN_SHADOW_COUNT=4 $OSCFLAGS"
+FLAGS=" -I../rtl -I../.. -I../../sanitizer_common -I../../../include -m64 -Wall -Werror -fno-exceptions -fno-rtti -DTSAN_GO -DSANITIZER_GO -DTSAN_SHADOW_COUNT=4 $OSCFLAGS"
if [ "$DEBUG" == "" ]; then
FLAGS+=" -DTSAN_DEBUG=0 -O3 -fomit-frame-pointer"
else
diff --git a/lib/tsan/go/test.c b/lib/tsan/go/test.c
index 2414a1e9925f7..902dfc915582b 100644
--- a/lib/tsan/go/test.c
+++ b/lib/tsan/go/test.c
@@ -13,20 +13,20 @@
#include <stdio.h>
-void __tsan_init();
+void __tsan_init(void **thr);
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);
-void __tsan_write(int goid, void *addr, void *pc);
-void __tsan_func_enter(int goid, void *pc);
-void __tsan_func_exit(int goid);
-void __tsan_malloc(int goid, void *p, unsigned long sz, void *pc);
+void __tsan_go_start(void *thr, void **chthr, void *pc);
+void __tsan_go_end(void *thr);
+void __tsan_read(void *thr, void *addr, void *pc);
+void __tsan_write(void *thr, void *addr, void *pc);
+void __tsan_func_enter(void *thr, void *pc);
+void __tsan_func_exit(void *thr);
+void __tsan_malloc(void *thr, void *p, unsigned long sz, void *pc);
void __tsan_free(void *p);
-void __tsan_acquire(int goid, void *addr);
-void __tsan_release(int goid, void *addr);
-void __tsan_release_merge(int goid, void *addr);
+void __tsan_acquire(void *thr, void *addr);
+void __tsan_release(void *thr, void *addr);
+void __tsan_release_merge(void *thr, void *addr);
int __tsan_symbolize(void *pc, char **img, char **rtn, char **file, int *l) {
return 0;
@@ -35,19 +35,21 @@ int __tsan_symbolize(void *pc, char **img, char **rtn, char **file, int *l) {
char buf[10];
int main(void) {
- __tsan_init();
+ void *thr0 = 0;
+ __tsan_init(&thr0);
__tsan_map_shadow(buf, sizeof(buf) + 4096);
- __tsan_func_enter(0, &main);
- __tsan_malloc(0, buf, 10, 0);
- __tsan_release(0, buf);
- __tsan_release_merge(0, buf);
- __tsan_go_start(0, 1, 0);
- __tsan_write(1, buf, 0);
- __tsan_acquire(1, buf);
- __tsan_go_end(1);
- __tsan_read(0, buf, 0);
+ __tsan_func_enter(thr0, &main);
+ __tsan_malloc(thr0, buf, 10, 0);
+ __tsan_release(thr0, buf);
+ __tsan_release_merge(thr0, buf);
+ void *thr1 = 0;
+ __tsan_go_start(thr0, &thr1, 0);
+ __tsan_write(thr1, buf, 0);
+ __tsan_acquire(thr1, buf);
+ __tsan_go_end(thr1);
+ __tsan_read(thr0, buf, 0);
__tsan_free(buf);
- __tsan_func_exit(0);
+ __tsan_func_exit(thr0);
__tsan_fini();
return 0;
}
diff --git a/lib/tsan/go/tsan_go.cc b/lib/tsan/go/tsan_go.cc
index 360608a0cf1ba..957d58211281e 100644
--- a/lib/tsan/go/tsan_go.cc
+++ b/lib/tsan/go/tsan_go.cc
@@ -18,10 +18,6 @@
namespace __tsan {
-const int kMaxGoroutinesEver = 128*1024;
-
-static ThreadState *goroutines[kMaxGoroutinesEver];
-
void InitializeInterceptors() {
}
@@ -80,20 +76,18 @@ ReportStack *SymbolizeCode(uptr addr) {
extern "C" {
-static void AllocGoroutine(int tid) {
- if (tid >= kMaxGoroutinesEver) {
- Printf("FATAL: Reached goroutine limit\n");
- Die();
- }
+static ThreadState *main_thr;
+
+static ThreadState *AllocGoroutine() {
ThreadState *thr = (ThreadState*)internal_alloc(MBlockThreadContex,
sizeof(ThreadState));
internal_memset(thr, 0, sizeof(*thr));
- goroutines[tid] = thr;
+ return thr;
}
-void __tsan_init() {
- AllocGoroutine(0);
- ThreadState *thr = goroutines[0];
+void __tsan_init(ThreadState **thrp) {
+ ThreadState *thr = AllocGoroutine();
+ main_thr = *thrp = thr;
thr->in_rtl++;
Initialize(thr);
thr->in_rtl--;
@@ -101,7 +95,7 @@ void __tsan_init() {
void __tsan_fini() {
// FIXME: Not necessary thread 0.
- ThreadState *thr = goroutines[0];
+ ThreadState *thr = main_thr;
thr->in_rtl++;
int res = Finalize(thr);
thr->in_rtl--;
@@ -112,44 +106,37 @@ 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);
+void __tsan_read(ThreadState *thr, void *addr, void *pc) {
+ MemoryRead(thr, (uptr)pc, (uptr)addr, kSizeLog1);
}
-void __tsan_write(int goid, void *addr, void *pc) {
- ThreadState *thr = goroutines[goid];
- MemoryAccess(thr, (uptr)pc, (uptr)addr, 0, true);
+void __tsan_write(ThreadState *thr, void *addr, void *pc) {
+ MemoryWrite(thr, (uptr)pc, (uptr)addr, kSizeLog1);
}
-void __tsan_read_range(int goid, void *addr, uptr size, uptr step, void *pc) {
- ThreadState *thr = goroutines[goid];
- for (uptr i = 0; i < size; i += step)
- MemoryAccess(thr, (uptr)pc, (uptr)addr + i, 0, false);
+void __tsan_read_range(ThreadState *thr, void *addr, uptr size, uptr step,
+ void *pc) {
+ MemoryAccessRangeStep(thr, (uptr)pc, (uptr)addr, size, step, false);
}
-void __tsan_write_range(int goid, void *addr, uptr size, uptr step, void *pc) {
- ThreadState *thr = goroutines[goid];
- for (uptr i = 0; i < size; i += step)
- MemoryAccess(thr, (uptr)pc, (uptr)addr + i, 0, true);
+void __tsan_write_range(ThreadState *thr, void *addr, uptr size, uptr step,
+ void *pc) {
+ MemoryAccessRangeStep(thr, (uptr)pc, (uptr)addr, size, step, true);
}
-void __tsan_func_enter(int goid, void *pc) {
- ThreadState *thr = goroutines[goid];
+void __tsan_func_enter(ThreadState *thr, void *pc) {
FuncEntry(thr, (uptr)pc);
}
-void __tsan_func_exit(int goid) {
- ThreadState *thr = goroutines[goid];
+void __tsan_func_exit(ThreadState *thr) {
FuncExit(thr);
}
-void __tsan_malloc(int goid, void *p, uptr sz, void *pc) {
- ThreadState *thr = goroutines[goid];
+void __tsan_malloc(ThreadState *thr, void *p, uptr sz, void *pc) {
if (thr == 0) // probably before __tsan_init()
return;
thr->in_rtl++;
- MemoryRangeImitateWrite(thr, (uptr)pc, (uptr)p, sz);
+ MemoryResetRange(thr, (uptr)pc, (uptr)p, sz);
thr->in_rtl--;
}
@@ -157,56 +144,47 @@ void __tsan_free(void *p) {
(void)p;
}
-void __tsan_go_start(int pgoid, int chgoid, void *pc) {
- if (chgoid == 0)
- return;
- AllocGoroutine(chgoid);
- ThreadState *thr = goroutines[chgoid];
- ThreadState *parent = goroutines[pgoid];
+void __tsan_go_start(ThreadState *parent, ThreadState **pthr, void *pc) {
+ ThreadState *thr = AllocGoroutine();
+ *pthr = thr;
thr->in_rtl++;
parent->in_rtl++;
- int goid2 = ThreadCreate(parent, (uptr)pc, 0, true);
- ThreadStart(thr, goid2, 0);
+ int goid = ThreadCreate(parent, (uptr)pc, 0, true);
+ ThreadStart(thr, goid, 0);
parent->in_rtl--;
thr->in_rtl--;
}
-void __tsan_go_end(int goid) {
- ThreadState *thr = goroutines[goid];
+void __tsan_go_end(ThreadState *thr) {
thr->in_rtl++;
ThreadFinish(thr);
thr->in_rtl--;
internal_free(thr);
- goroutines[goid] = 0;
}
-void __tsan_acquire(int goid, void *addr) {
- ThreadState *thr = goroutines[goid];
+void __tsan_acquire(ThreadState *thr, void *addr) {
thr->in_rtl++;
Acquire(thr, 0, (uptr)addr);
thr->in_rtl--;
}
-void __tsan_release(int goid, void *addr) {
- ThreadState *thr = goroutines[goid];
+void __tsan_release(ThreadState *thr, void *addr) {
thr->in_rtl++;
ReleaseStore(thr, 0, (uptr)addr);
thr->in_rtl--;
}
-void __tsan_release_merge(int goid, void *addr) {
- ThreadState *thr = goroutines[goid];
+void __tsan_release_merge(ThreadState *thr, void *addr) {
thr->in_rtl++;
Release(thr, 0, (uptr)addr);
thr->in_rtl--;
}
-void __tsan_finalizer_goroutine(int goid) {
- ThreadState *thr = goroutines[goid];
+void __tsan_finalizer_goroutine(ThreadState *thr) {
AcquireGlobal(thr, 0);
}
-#ifdef _WIN32
+#if SANITIZER_WINDOWS
// MinGW gcc emits calls to the function.
void ___chkstk_ms(void) {
// The implementation must be along the lines of:
@@ -242,3 +220,11 @@ void ___chkstk_ms(void) {
} // extern "C"
} // namespace __tsan
+
+namespace __sanitizer {
+
+void SymbolizerPrepareForSandboxing() {
+ // Nothing to do here for Go.
+}
+
+} // namespace __sanitizer