diff options
Diffstat (limited to 'lib/tsan/go/tsan_go.cc')
-rw-r--r-- | lib/tsan/go/tsan_go.cc | 138 |
1 files changed, 79 insertions, 59 deletions
diff --git a/lib/tsan/go/tsan_go.cc b/lib/tsan/go/tsan_go.cc index df54bb8e216cd..cccf72cedd27e 100644 --- a/lib/tsan/go/tsan_go.cc +++ b/lib/tsan/go/tsan_go.cc @@ -28,19 +28,15 @@ bool IsExpectedReport(uptr addr, uptr size) { return false; } -void internal_start_thread(void(*func)(void*), void *arg) { +void *internal_start_thread(void(*func)(void*), void *arg) { + return 0; } -ReportLocation *SymbolizeData(uptr addr) { - return 0; +void internal_join_thread(void *th) { } -ReportStack *NewReportStackEntry(uptr addr) { - ReportStack *ent = (ReportStack*)internal_alloc(MBlockReportStack, - sizeof(ReportStack)); - internal_memset(ent, 0, sizeof(*ent)); - ent->pc = addr; - return ent; +ReportLocation *SymbolizeData(uptr addr) { + return 0; } void *internal_alloc(MBlockType typ, uptr sz) { @@ -51,25 +47,31 @@ void internal_free(void *p) { InternalFree(p); } +struct SymbolizeContext { + uptr pc; + char *func; + char *file; + uptr line; + uptr off; + uptr res; +}; + // Callback into Go. -extern "C" int __tsan_symbolize(uptr pc, char **func, char **file, - int *line, int *off); - -ReportStack *SymbolizeCode(uptr addr) { - ReportStack *s = (ReportStack*)internal_alloc(MBlockReportStack, - sizeof(ReportStack)); - internal_memset(s, 0, sizeof(*s)); - s->pc = addr; - char *func = 0, *file = 0; - int line = 0, off = 0; - if (__tsan_symbolize(addr, &func, &file, &line, &off)) { - s->offset = off; - s->func = internal_strdup(func ? func : "??"); - s->file = internal_strdup(file ? file : "-"); - s->line = line; - s->col = 0; - free(func); - free(file); +static void (*symbolize_cb)(SymbolizeContext *ctx); + +SymbolizedStack *SymbolizeCode(uptr addr) { + SymbolizedStack *s = SymbolizedStack::New(addr); + SymbolizeContext ctx; + internal_memset(&ctx, 0, sizeof(ctx)); + ctx.pc = addr; + symbolize_cb(&ctx); + if (ctx.res) { + AddressInfo &info = s->info; + info.module_offset = ctx.off; + info.function = internal_strdup(ctx.func ? ctx.func : "??"); + info.file = internal_strdup(ctx.file ? ctx.file : "-"); + info.line = ctx.line; + info.column = 0; } return s; } @@ -77,6 +79,7 @@ ReportStack *SymbolizeCode(uptr addr) { extern "C" { static ThreadState *main_thr; +static bool inited; static ThreadState *AllocGoroutine() { ThreadState *thr = (ThreadState*)internal_alloc(MBlockThreadContex, @@ -85,20 +88,18 @@ static ThreadState *AllocGoroutine() { return thr; } -void __tsan_init(ThreadState **thrp) { +void __tsan_init(ThreadState **thrp, void (*cb)(SymbolizeContext *cb)) { + symbolize_cb = cb; ThreadState *thr = AllocGoroutine(); main_thr = *thrp = thr; - thr->in_rtl++; Initialize(thr); - thr->in_rtl--; + inited = true; } void __tsan_fini() { // FIXME: Not necessary thread 0. ThreadState *thr = main_thr; - thr->in_rtl++; int res = Finalize(thr); - thr->in_rtl--; exit(res); } @@ -110,19 +111,31 @@ void __tsan_read(ThreadState *thr, void *addr, void *pc) { MemoryRead(thr, (uptr)pc, (uptr)addr, kSizeLog1); } +void __tsan_read_pc(ThreadState *thr, void *addr, uptr callpc, uptr pc) { + if (callpc != 0) + FuncEntry(thr, callpc); + MemoryRead(thr, (uptr)pc, (uptr)addr, kSizeLog1); + if (callpc != 0) + FuncExit(thr); +} + void __tsan_write(ThreadState *thr, void *addr, void *pc) { MemoryWrite(thr, (uptr)pc, (uptr)addr, kSizeLog1); } -void __tsan_read_range(ThreadState *thr, void *addr, uptr size, uptr step, - void *pc) { - (void)step; +void __tsan_write_pc(ThreadState *thr, void *addr, uptr callpc, uptr pc) { + if (callpc != 0) + FuncEntry(thr, callpc); + MemoryWrite(thr, (uptr)pc, (uptr)addr, kSizeLog1); + if (callpc != 0) + FuncExit(thr); +} + +void __tsan_read_range(ThreadState *thr, void *addr, uptr size, uptr pc) { MemoryAccessRange(thr, (uptr)pc, (uptr)addr, size, false); } -void __tsan_write_range(ThreadState *thr, void *addr, uptr size, uptr step, - void *pc) { - (void)step; +void __tsan_write_range(ThreadState *thr, void *addr, uptr size, uptr pc) { MemoryAccessRange(thr, (uptr)pc, (uptr)addr, size, true); } @@ -134,58 +147,65 @@ void __tsan_func_exit(ThreadState *thr) { FuncExit(thr); } -void __tsan_malloc(ThreadState *thr, void *p, uptr sz, void *pc) { - if (thr == 0) // probably before __tsan_init() +void __tsan_malloc(void *p, uptr sz) { + if (!inited) return; - thr->in_rtl++; - MemoryResetRange(thr, (uptr)pc, (uptr)p, sz); - thr->in_rtl--; -} - -void __tsan_free(void *p) { - (void)p; + MemoryResetRange(0, 0, (uptr)p, sz); } void __tsan_go_start(ThreadState *parent, ThreadState **pthr, void *pc) { ThreadState *thr = AllocGoroutine(); *pthr = thr; - thr->in_rtl++; - parent->in_rtl++; int goid = ThreadCreate(parent, (uptr)pc, 0, true); ThreadStart(thr, goid, 0); - parent->in_rtl--; - thr->in_rtl--; } void __tsan_go_end(ThreadState *thr) { - thr->in_rtl++; ThreadFinish(thr); - thr->in_rtl--; internal_free(thr); } void __tsan_acquire(ThreadState *thr, void *addr) { - thr->in_rtl++; Acquire(thr, 0, (uptr)addr); - thr->in_rtl--; } void __tsan_release(ThreadState *thr, void *addr) { - thr->in_rtl++; ReleaseStore(thr, 0, (uptr)addr); - thr->in_rtl--; } void __tsan_release_merge(ThreadState *thr, void *addr) { - thr->in_rtl++; Release(thr, 0, (uptr)addr); - thr->in_rtl--; } void __tsan_finalizer_goroutine(ThreadState *thr) { AcquireGlobal(thr, 0); } +void __tsan_mutex_before_lock(ThreadState *thr, uptr addr, uptr write) { +} + +void __tsan_mutex_after_lock(ThreadState *thr, uptr addr, uptr write) { + if (write) + MutexLock(thr, 0, addr); + else + MutexReadLock(thr, 0, addr); +} + +void __tsan_mutex_before_unlock(ThreadState *thr, uptr addr, uptr write) { + if (write) + MutexUnlock(thr, 0, addr); + else + MutexReadUnlock(thr, 0, addr); +} + +void __tsan_go_ignore_sync_begin(ThreadState *thr) { + ThreadIgnoreSyncBegin(thr, 0); +} + +void __tsan_go_ignore_sync_end(ThreadState *thr) { + ThreadIgnoreSyncEnd(thr, 0); +} + } // extern "C" } // namespace __tsan |