summaryrefslogtreecommitdiff
path: root/lib/tsan/go/tsan_go.cc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/tsan/go/tsan_go.cc')
-rw-r--r--lib/tsan/go/tsan_go.cc138
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