diff options
Diffstat (limited to 'lib/tsan/go')
-rwxr-xr-x | lib/tsan/go/buildgo.sh | 5 | ||||
-rw-r--r-- | lib/tsan/go/test.c | 46 | ||||
-rw-r--r-- | lib/tsan/go/tsan_go.cc | 96 |
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 |