summaryrefslogtreecommitdiff
path: root/libsanitizer/tsan
diff options
context:
space:
mode:
authorkcc <kcc@138bc75d-0d04-0410-961f-82ee72b054a4>2013-01-23 11:41:33 +0000
committerkcc <kcc@138bc75d-0d04-0410-961f-82ee72b054a4>2013-01-23 11:41:33 +0000
commit4a2c1ffc3bc03c1f519fe1ef62cafeda13481fe2 (patch)
tree80989bd161e60d01560788cb7427eb644b227884 /libsanitizer/tsan
parentbc5663df31f641cce031d61b31540dd88a473cb5 (diff)
downloadgcc-4a2c1ffc3bc03c1f519fe1ef62cafeda13481fe2.tar.gz
libsanitizer merge from upstream r173241
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@195404 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libsanitizer/tsan')
-rw-r--r--libsanitizer/tsan/tsan_fd.cc6
-rw-r--r--libsanitizer/tsan/tsan_fd.h1
-rw-r--r--libsanitizer/tsan/tsan_interceptors.cc89
-rw-r--r--libsanitizer/tsan/tsan_mman.cc1
-rw-r--r--libsanitizer/tsan/tsan_report.cc9
-rw-r--r--libsanitizer/tsan/tsan_report.h1
-rw-r--r--libsanitizer/tsan/tsan_rtl_mutex.cc1
-rw-r--r--libsanitizer/tsan/tsan_rtl_report.cc53
-rw-r--r--libsanitizer/tsan/tsan_stat.cc7
-rw-r--r--libsanitizer/tsan/tsan_stat.h7
-rw-r--r--libsanitizer/tsan/tsan_symbolize.cc50
-rw-r--r--libsanitizer/tsan/tsan_symbolize.h3
12 files changed, 129 insertions, 99 deletions
diff --git a/libsanitizer/tsan/tsan_fd.cc b/libsanitizer/tsan/tsan_fd.cc
index 9aca9c51b38..f640c4f893e 100644
--- a/libsanitizer/tsan/tsan_fd.cc
+++ b/libsanitizer/tsan/tsan_fd.cc
@@ -162,6 +162,12 @@ void FdRelease(ThreadState *thr, uptr pc, int fd) {
MemoryRead8Byte(thr, pc, (uptr)d);
}
+void FdAccess(ThreadState *thr, uptr pc, int fd) {
+ DPrintf("#%d: FdAccess(%d)\n", thr->tid, fd);
+ FdDesc *d = fddesc(thr, pc, fd);
+ MemoryRead8Byte(thr, pc, (uptr)d);
+}
+
void FdClose(ThreadState *thr, uptr pc, int fd) {
DPrintf("#%d: FdClose(%d)\n", thr->tid, fd);
FdDesc *d = fddesc(thr, pc, fd);
diff --git a/libsanitizer/tsan/tsan_fd.h b/libsanitizer/tsan/tsan_fd.h
index b4189a37df5..3306873223e 100644
--- a/libsanitizer/tsan/tsan_fd.h
+++ b/libsanitizer/tsan/tsan_fd.h
@@ -39,6 +39,7 @@ namespace __tsan {
void FdInit();
void FdAcquire(ThreadState *thr, uptr pc, int fd);
void FdRelease(ThreadState *thr, uptr pc, int fd);
+void FdAccess(ThreadState *thr, uptr pc, int fd);
void FdClose(ThreadState *thr, uptr pc, int fd);
void FdFileCreate(ThreadState *thr, uptr pc, int fd);
void FdDup(ThreadState *thr, uptr pc, int oldfd, int newfd);
diff --git a/libsanitizer/tsan/tsan_interceptors.cc b/libsanitizer/tsan/tsan_interceptors.cc
index 88acebf8e81..d8f66de2327 100644
--- a/libsanitizer/tsan/tsan_interceptors.cc
+++ b/libsanitizer/tsan/tsan_interceptors.cc
@@ -1239,33 +1239,6 @@ TSAN_INTERCEPTOR(int, pipe2, int *pipefd, int flags) {
return res;
}
-TSAN_INTERCEPTOR(long_t, read, int fd, void *buf, long_t sz) {
- SCOPED_TSAN_INTERCEPTOR(read, fd, buf, sz);
- int res = REAL(read)(fd, buf, sz);
- if (res >= 0 && fd >= 0) {
- FdAcquire(thr, pc, fd);
- }
- return res;
-}
-
-TSAN_INTERCEPTOR(long_t, pread, int fd, void *buf, long_t sz, unsigned off) {
- SCOPED_TSAN_INTERCEPTOR(pread, fd, buf, sz, off);
- int res = REAL(pread)(fd, buf, sz, off);
- if (res >= 0 && fd >= 0) {
- FdAcquire(thr, pc, fd);
- }
- return res;
-}
-
-TSAN_INTERCEPTOR(long_t, pread64, int fd, void *buf, long_t sz, u64 off) {
- SCOPED_TSAN_INTERCEPTOR(pread64, fd, buf, sz, off);
- int res = REAL(pread64)(fd, buf, sz, off);
- if (res >= 0 && fd >= 0) {
- FdAcquire(thr, pc, fd);
- }
- return res;
-}
-
TSAN_INTERCEPTOR(long_t, readv, int fd, void *vec, int cnt) {
SCOPED_TSAN_INTERCEPTOR(readv, fd, vec, cnt);
int res = REAL(readv)(fd, vec, cnt);
@@ -1284,30 +1257,6 @@ TSAN_INTERCEPTOR(long_t, preadv64, int fd, void *vec, int cnt, u64 off) {
return res;
}
-TSAN_INTERCEPTOR(long_t, write, int fd, void *buf, long_t sz) {
- SCOPED_TSAN_INTERCEPTOR(write, fd, buf, sz);
- if (fd >= 0)
- FdRelease(thr, pc, fd);
- int res = REAL(write)(fd, buf, sz);
- return res;
-}
-
-TSAN_INTERCEPTOR(long_t, pwrite, int fd, void *buf, long_t sz, unsigned off) {
- SCOPED_TSAN_INTERCEPTOR(pwrite, fd, buf, sz, off);
- if (fd >= 0)
- FdRelease(thr, pc, fd);
- int res = REAL(pwrite)(fd, buf, sz, off);
- return res;
-}
-
-TSAN_INTERCEPTOR(long_t, pwrite64, int fd, void *buf, long_t sz, u64 off) {
- SCOPED_TSAN_INTERCEPTOR(pwrite64, fd, buf, sz, off);
- if (fd >= 0)
- FdRelease(thr, pc, fd);
- int res = REAL(pwrite64)(fd, buf, sz, off);
- return res;
-}
-
TSAN_INTERCEPTOR(long_t, writev, int fd, void *vec, int cnt) {
SCOPED_TSAN_INTERCEPTOR(writev, fd, vec, cnt);
if (fd >= 0)
@@ -1449,6 +1398,8 @@ TSAN_INTERCEPTOR(int, epoll_ctl, int epfd, int op, int fd, void *ev) {
FdRelease(thr, pc, epfd);
}
int res = REAL(epoll_ctl)(epfd, op, fd, ev);
+ if (fd >= 0)
+ FdAccess(thr, pc, fd);
return res;
}
@@ -1641,6 +1592,33 @@ TSAN_INTERCEPTOR(int, fork, int fake) {
return pid;
}
+struct TsanInterceptorContext {
+ ThreadState *thr;
+ const uptr caller_pc;
+ const uptr pc;
+};
+
+#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
+ MemoryAccessRange(((TsanInterceptorContext*)ctx)->thr, \
+ ((TsanInterceptorContext*)ctx)->pc, \
+ (uptr)ptr, size, true)
+#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \
+ MemoryAccessRange(((TsanInterceptorContext*)ctx)->thr, \
+ ((TsanInterceptorContext*)ctx)->pc, \
+ (uptr)ptr, size, false)
+#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \
+ SCOPED_TSAN_INTERCEPTOR(func, __VA_ARGS__) \
+ TsanInterceptorContext _ctx = {thr, caller_pc, pc}; \
+ ctx = (void*)&_ctx; \
+ (void)ctx;
+#define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \
+ FdAcquire(((TsanInterceptorContext*)ctx)->thr, pc, fd)
+#define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \
+ FdRelease(((TsanInterceptorContext*)ctx)->thr, pc, fd)
+#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \
+ ThreadSetName(((TsanInterceptorContext*)ctx)->thr, name)
+#include "sanitizer_common/sanitizer_common_interceptors.inc"
+
namespace __tsan {
void ProcessPendingSignals(ThreadState *thr) {
@@ -1675,6 +1653,7 @@ void ProcessPendingSignals(ThreadState *thr) {
(uptr)sigactions[sig].sa_sigaction :
(uptr)sigactions[sig].sa_handler;
stack.Init(&pc, 1);
+ Lock l(&ctx->thread_mtx);
ScopedReport rep(ReportTypeErrnoInSignal);
if (!IsFiredSuppression(ctx, rep, stack)) {
rep.AddStack(&stack);
@@ -1703,6 +1682,8 @@ void InitializeInterceptors() {
REAL(memcpy) = internal_memcpy;
REAL(memcmp) = internal_memcmp;
+ SANITIZER_COMMON_INTERCEPTORS_INIT;
+
TSAN_INTERCEPT(longjmp);
TSAN_INTERCEPT(siglongjmp);
@@ -1806,14 +1787,8 @@ void InitializeInterceptors() {
TSAN_INTERCEPT(pipe);
TSAN_INTERCEPT(pipe2);
- TSAN_INTERCEPT(read);
- TSAN_INTERCEPT(pread);
- TSAN_INTERCEPT(pread64);
TSAN_INTERCEPT(readv);
TSAN_INTERCEPT(preadv64);
- TSAN_INTERCEPT(write);
- TSAN_INTERCEPT(pwrite);
- TSAN_INTERCEPT(pwrite64);
TSAN_INTERCEPT(writev);
TSAN_INTERCEPT(pwritev64);
TSAN_INTERCEPT(send);
diff --git a/libsanitizer/tsan/tsan_mman.cc b/libsanitizer/tsan/tsan_mman.cc
index 9a8a524f262..f4fafaf77f0 100644
--- a/libsanitizer/tsan/tsan_mman.cc
+++ b/libsanitizer/tsan/tsan_mman.cc
@@ -46,6 +46,7 @@ static void SignalUnsafeCall(ThreadState *thr, uptr pc) {
Context *ctx = CTX();
StackTrace stack;
stack.ObtainCurrent(thr, pc);
+ Lock l(&ctx->thread_mtx);
ScopedReport rep(ReportTypeSignalUnsafe);
if (!IsFiredSuppression(ctx, rep, stack)) {
rep.AddStack(&stack);
diff --git a/libsanitizer/tsan/tsan_report.cc b/libsanitizer/tsan/tsan_report.cc
index ca352662902..f99fd2ea105 100644
--- a/libsanitizer/tsan/tsan_report.cc
+++ b/libsanitizer/tsan/tsan_report.cc
@@ -102,16 +102,17 @@ static void PrintMop(const ReportMop *mop, bool first) {
static void PrintLocation(const ReportLocation *loc) {
char thrbuf[kThreadBufSize];
if (loc->type == ReportLocationGlobal) {
- Printf(" Location is global '%s' of size %zu at %zx %s:%d (%s+%p)\n\n",
- loc->name, loc->size, loc->addr, loc->file, loc->line,
- loc->module, loc->offset);
+ Printf(" Location is global '%s' of size %zu at %zx (%s+%p)\n\n",
+ loc->name, loc->size, loc->addr, loc->module, loc->offset);
} else if (loc->type == ReportLocationHeap) {
char thrbuf[kThreadBufSize];
Printf(" Location is heap block of size %zu at %p allocated by %s:\n",
loc->size, loc->addr, thread_name(thrbuf, loc->tid));
PrintStack(loc->stack);
} else if (loc->type == ReportLocationStack) {
- Printf(" Location is stack of %s\n\n", thread_name(thrbuf, loc->tid));
+ Printf(" Location is stack of %s.\n\n", thread_name(thrbuf, loc->tid));
+ } else if (loc->type == ReportLocationTLS) {
+ Printf(" Location is TLS of %s.\n\n", thread_name(thrbuf, loc->tid));
} else if (loc->type == ReportLocationFD) {
Printf(" Location is file descriptor %d created by %s at:\n",
loc->fd, thread_name(thrbuf, loc->tid));
diff --git a/libsanitizer/tsan/tsan_report.h b/libsanitizer/tsan/tsan_report.h
index 23fbc684209..42f52af9e37 100644
--- a/libsanitizer/tsan/tsan_report.h
+++ b/libsanitizer/tsan/tsan_report.h
@@ -56,6 +56,7 @@ enum ReportLocationType {
ReportLocationGlobal,
ReportLocationHeap,
ReportLocationStack,
+ ReportLocationTLS,
ReportLocationFD
};
diff --git a/libsanitizer/tsan/tsan_rtl_mutex.cc b/libsanitizer/tsan/tsan_rtl_mutex.cc
index 8dd0e6d4d9b..db97e1d9853 100644
--- a/libsanitizer/tsan/tsan_rtl_mutex.cc
+++ b/libsanitizer/tsan/tsan_rtl_mutex.cc
@@ -53,6 +53,7 @@ void MutexDestroy(ThreadState *thr, uptr pc, uptr addr) {
&& s->owner_tid != SyncVar::kInvalidTid
&& !s->is_broken) {
s->is_broken = true;
+ Lock l(&ctx->thread_mtx);
ScopedReport rep(ReportTypeMutexDestroyLocked);
rep.AddMutex(s);
StackTrace trace;
diff --git a/libsanitizer/tsan/tsan_rtl_report.cc b/libsanitizer/tsan/tsan_rtl_report.cc
index b65b24fce89..c4256da412a 100644
--- a/libsanitizer/tsan/tsan_rtl_report.cc
+++ b/libsanitizer/tsan/tsan_rtl_report.cc
@@ -119,6 +119,7 @@ static ReportStack *SymbolizeStack(const StackTrace& trace) {
ScopedReport::ScopedReport(ReportType typ) {
ctx_ = CTX();
+ ctx_->thread_mtx.CheckLocked();
void *mem = internal_alloc(MBlockReport, sizeof(ReportDesc));
rep_ = new(mem) ReportDesc;
rep_->typ = typ;
@@ -185,15 +186,37 @@ void ScopedReport::AddThread(const ThreadContext *tctx) {
#ifndef TSAN_GO
static ThreadContext *FindThread(int unique_id) {
- CTX()->thread_mtx.CheckLocked();
+ Context *ctx = CTX();
+ ctx->thread_mtx.CheckLocked();
for (unsigned i = 0; i < kMaxTid; i++) {
- ThreadContext *tctx = CTX()->threads[i];
+ ThreadContext *tctx = ctx->threads[i];
if (tctx && tctx->unique_id == unique_id) {
return tctx;
}
}
return 0;
}
+
+ThreadContext *IsThreadStackOrTls(uptr addr, bool *is_stack) {
+ Context *ctx = CTX();
+ ctx->thread_mtx.CheckLocked();
+ for (unsigned i = 0; i < kMaxTid; i++) {
+ ThreadContext *tctx = ctx->threads[i];
+ if (tctx == 0 || tctx->status != ThreadStatusRunning)
+ continue;
+ ThreadState *thr = tctx->thr;
+ CHECK(thr);
+ if (addr >= thr->stk_addr && addr < thr->stk_addr + thr->stk_size) {
+ *is_stack = true;
+ return tctx;
+ }
+ if (addr >= thr->tls_addr && addr < thr->tls_addr + thr->tls_size) {
+ *is_stack = false;
+ return tctx;
+ }
+ }
+ return 0;
+}
#endif
void ScopedReport::AddMutex(const SyncVar *s) {
@@ -274,25 +297,21 @@ void ScopedReport::AddLocation(uptr addr, uptr size) {
AddThread(tctx);
return;
}
-#endif
- ReportStack *symb = SymbolizeData(addr);
- if (symb) {
+ bool is_stack = false;
+ if (ThreadContext *tctx = IsThreadStackOrTls(addr, &is_stack)) {
void *mem = internal_alloc(MBlockReportLoc, sizeof(ReportLocation));
ReportLocation *loc = new(mem) ReportLocation();
rep_->locs.PushBack(loc);
- loc->type = ReportLocationGlobal;
- loc->addr = addr;
- loc->size = size;
- loc->module = symb->module ? internal_strdup(symb->module) : 0;
- loc->offset = symb->offset;
- loc->tid = 0;
- loc->name = symb->func ? internal_strdup(symb->func) : 0;
- loc->file = symb->file ? internal_strdup(symb->file) : 0;
- loc->line = symb->line;
- loc->stack = 0;
- internal_free(symb);
+ loc->type = is_stack ? ReportLocationStack : ReportLocationTLS;
+ loc->tid = tctx->tid;
+ AddThread(tctx);
+ }
+ ReportLocation *loc = SymbolizeData(addr);
+ if (loc) {
+ rep_->locs.PushBack(loc);
return;
}
+#endif
}
#ifndef TSAN_GO
@@ -386,7 +405,7 @@ static bool HandleRacyStacks(ThreadState *thr, const StackTrace (&traces)[2],
uptr addr_min, uptr addr_max) {
Context *ctx = CTX();
bool equal_stack = false;
- RacyStacks hash = {};
+ RacyStacks hash;
if (flags()->suppress_equal_stacks) {
hash.hash[0] = md5_hash(traces[0].Begin(), traces[0].Size() * sizeof(uptr));
hash.hash[1] = md5_hash(traces[1].Begin(), traces[1].Size() * sizeof(uptr));
diff --git a/libsanitizer/tsan/tsan_stat.cc b/libsanitizer/tsan/tsan_stat.cc
index 394c9111626..105d0bc2375 100644
--- a/libsanitizer/tsan/tsan_stat.cc
+++ b/libsanitizer/tsan/tsan_stat.cc
@@ -202,6 +202,7 @@ void StatOutput(u64 *stat) {
name[StatInt_pipe] = " pipe ";
name[StatInt_pipe2] = " pipe2 ";
name[StatInt_read] = " read ";
+ name[StatInt_prctl] = " prctl ";
name[StatInt_pread] = " pread ";
name[StatInt_pread64] = " pread64 ";
name[StatInt_readv] = " readv ";
@@ -233,6 +234,12 @@ void StatOutput(u64 *stat) {
name[StatInt_nanosleep] = " nanosleep ";
name[StatInt_gettimeofday] = " gettimeofday ";
name[StatInt_fork] = " fork ";
+ name[StatInt_vscanf] = " vscanf ";
+ name[StatInt_vsscanf] = " vsscanf ";
+ name[StatInt_vfscanf] = " vfscanf ";
+ name[StatInt_scanf] = " scanf ";
+ name[StatInt_sscanf] = " sscanf ";
+ name[StatInt_fscanf] = " fscanf ";
name[StatAnnotation] = "Dynamic annotations ";
name[StatAnnotateHappensBefore] = " HappensBefore ";
diff --git a/libsanitizer/tsan/tsan_stat.h b/libsanitizer/tsan/tsan_stat.h
index cdd57365bae..f40d3a2ac5e 100644
--- a/libsanitizer/tsan/tsan_stat.h
+++ b/libsanitizer/tsan/tsan_stat.h
@@ -197,6 +197,7 @@ enum StatType {
StatInt_pipe,
StatInt_pipe2,
StatInt_read,
+ StatInt_prctl,
StatInt_pread,
StatInt_pread64,
StatInt_readv,
@@ -232,6 +233,12 @@ enum StatType {
StatInt_nanosleep,
StatInt_gettimeofday,
StatInt_fork,
+ StatInt_vscanf,
+ StatInt_vsscanf,
+ StatInt_vfscanf,
+ StatInt_scanf,
+ StatInt_sscanf,
+ StatInt_fscanf,
// Dynamic annotations.
StatAnnotation,
diff --git a/libsanitizer/tsan/tsan_symbolize.cc b/libsanitizer/tsan/tsan_symbolize.cc
index 50a4eaa518b..015b98717f1 100644
--- a/libsanitizer/tsan/tsan_symbolize.cc
+++ b/libsanitizer/tsan/tsan_symbolize.cc
@@ -27,21 +27,24 @@ ReportStack *NewReportStackEntry(uptr addr) {
return ent;
}
+// Strip module path to make output shorter.
+static char *StripModuleName(const char *module) {
+ if (module == 0)
+ return 0;
+ const char *short_module_name = internal_strrchr(module, '/');
+ if (short_module_name)
+ short_module_name += 1;
+ else
+ short_module_name = module;
+ return internal_strdup(short_module_name);
+}
+
static ReportStack *NewReportStackEntry(const AddressInfo &info) {
ReportStack *ent = NewReportStackEntry(info.address);
- if (info.module) {
- // Strip module path to make output shorter.
- const char *short_module_name = internal_strrchr(info.module, '/');
- if (short_module_name)
- short_module_name += 1;
- else
- short_module_name = info.module;
- ent->module = internal_strdup(short_module_name);
- }
+ ent->module = StripModuleName(info.module);
ent->offset = info.module_offset;
- if (info.function) {
+ if (info.function)
ent->func = internal_strdup(info.function);
- }
if (info.file)
ent->file = internal_strdup(info.file);
ent->line = info.line;
@@ -76,14 +79,23 @@ ReportStack *SymbolizeCode(uptr addr) {
return SymbolizeCodeAddr2Line(addr);
}
-ReportStack *SymbolizeData(uptr addr) {
- if (flags()->external_symbolizer_path[0]) {
- AddressInfo frame;
- if (!__sanitizer::SymbolizeData(addr, &frame))
- return 0;
- return NewReportStackEntry(frame);
- }
- return SymbolizeDataAddr2Line(addr);
+ReportLocation *SymbolizeData(uptr addr) {
+ if (flags()->external_symbolizer_path[0] == 0)
+ return 0;
+ DataInfo info;
+ if (!__sanitizer::SymbolizeData(addr, &info))
+ return 0;
+ ReportLocation *ent = (ReportLocation*)internal_alloc(MBlockReportStack,
+ sizeof(ReportLocation));
+ internal_memset(ent, 0, sizeof(*ent));
+ ent->type = ReportLocationGlobal;
+ ent->module = StripModuleName(info.module);
+ ent->offset = info.module_offset;
+ if (info.name)
+ ent->name = internal_strdup(info.name);
+ ent->addr = info.start;
+ ent->size = info.size;
+ return ent;
}
} // namespace __tsan
diff --git a/libsanitizer/tsan/tsan_symbolize.h b/libsanitizer/tsan/tsan_symbolize.h
index 6ac19ca5ccc..5275936a293 100644
--- a/libsanitizer/tsan/tsan_symbolize.h
+++ b/libsanitizer/tsan/tsan_symbolize.h
@@ -17,10 +17,9 @@
namespace __tsan {
ReportStack *SymbolizeCode(uptr addr);
-ReportStack *SymbolizeData(uptr addr);
+ReportLocation *SymbolizeData(uptr addr);
ReportStack *SymbolizeCodeAddr2Line(uptr addr);
-ReportStack *SymbolizeDataAddr2Line(uptr addr);
ReportStack *NewReportStackEntry(uptr addr);