Skip to content

Commit 55b47ca

Browse files
committed
tsan: fix trace handling when trace is reused between threads
llvm-svn: 169259
1 parent f9ae152 commit 55b47ca

File tree

5 files changed

+21
-6
lines changed

5 files changed

+21
-6
lines changed

compiler-rt/lib/tsan/rtl/tsan_defs.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,11 +128,17 @@ T max(T a, T b) {
128128
}
129129

130130
template<typename T>
131-
T RoundUp(T p, int align) {
131+
T RoundUp(T p, u64 align) {
132132
DCHECK_EQ(align & (align - 1), 0);
133133
return (T)(((u64)p + align - 1) & ~(align - 1));
134134
}
135135

136+
template<typename T>
137+
T RoundDown(T p, u64 align) {
138+
DCHECK_EQ(align & (align - 1), 0);
139+
return (T)((u64)p & ~(align - 1));
140+
}
141+
136142
struct MD5Hash {
137143
u64 hash[2];
138144
bool operator==(const MD5Hash &other) const;

compiler-rt/lib/tsan/rtl/tsan_rtl.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ void TraceSwitch(ThreadState *thr) {
286286
thr->nomalloc++;
287287
ScopedInRtl in_rtl;
288288
Lock l(&thr->trace.mtx);
289-
unsigned trace = (thr->fast_state.epoch() / kTracePartSize) % kTraceParts;
289+
unsigned trace = (thr->fast_state.epoch() / kTracePartSize) % TraceParts();
290290
TraceHeader *hdr = &thr->trace.headers[trace];
291291
hdr->epoch0 = thr->fast_state.epoch();
292292
hdr->stack0.ObtainCurrent(thr, 0);
@@ -303,6 +303,10 @@ uptr TraceSize() {
303303
return (uptr)(1ull << (kTracePartSizeBits + flags()->history_size + 1));
304304
}
305305

306+
uptr TraceParts() {
307+
return TraceSize() / kTracePartSize;
308+
}
309+
306310
#ifndef TSAN_GO
307311
extern "C" void __tsan_trace_switch() {
308312
TraceSwitch(cur_thread());

compiler-rt/lib/tsan/rtl/tsan_rtl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,7 @@ void AfterSleep(ThreadState *thr, uptr pc);
568568
void TraceSwitch(ThreadState *thr);
569569
uptr TraceTopPC(ThreadState *thr);
570570
uptr TraceSize();
571+
uptr TraceParts();
571572

572573
extern "C" void __tsan_trace_switch();
573574
void ALWAYS_INLINE INLINE TraceAddEvent(ThreadState *thr, FastState fs,

compiler-rt/lib/tsan/rtl/tsan_rtl_report.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,12 +265,12 @@ void RestoreStack(int tid, const u64 epoch, StackTrace *stk) {
265265
return;
266266
}
267267
Lock l(&trace->mtx);
268-
const int partidx = (epoch / (TraceSize() / kTraceParts)) % kTraceParts;
268+
const int partidx = (epoch / kTracePartSize) % TraceParts();
269269
TraceHeader* hdr = &trace->headers[partidx];
270270
if (epoch < hdr->epoch0)
271271
return;
272272
const u64 eend = epoch % TraceSize();
273-
const u64 ebegin = eend / kTracePartSize * kTracePartSize;
273+
const u64 ebegin = RoundDown(eend, kTracePartSize);
274274
DPrintf("#%d: RestoreStack epoch=%zu ebegin=%zu eend=%zu partidx=%d\n",
275275
tid, (uptr)epoch, (uptr)ebegin, (uptr)eend, partidx);
276276
InternalScopedBuffer<uptr> stack(1024); // FIXME: de-hardcode 1024

compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,9 @@ void ThreadStart(ThreadState *thr, int tid, uptr os_id) {
187187
CHECK_EQ(tctx->status, ThreadStatusCreated);
188188
tctx->status = ThreadStatusRunning;
189189
tctx->os_id = os_id;
190-
tctx->epoch0 = tctx->epoch1 + 1;
190+
// RoundUp so that one trace part does not contain events
191+
// from different threads.
192+
tctx->epoch0 = RoundUp(tctx->epoch1 + 1, kTracePartSize);
191193
tctx->epoch1 = (u64)-1;
192194
new(thr) ThreadState(CTX(), tid, tctx->unique_id,
193195
tctx->epoch0, stk_addr, stk_size,
@@ -205,6 +207,8 @@ void ThreadStart(ThreadState *thr, int tid, uptr os_id) {
205207
thr->clock.set(tid, tctx->epoch0);
206208
thr->clock.acquire(&tctx->sync);
207209
thr->fast_state.SetHistorySize(flags()->history_size);
210+
const uptr trace = (tctx->epoch0 / kTracePartSize) % TraceParts();
211+
thr->trace.headers[trace].epoch0 = tctx->epoch0;
208212
StatInc(thr, StatSyncAcquire);
209213
DPrintf("#%d: ThreadStart epoch=%zu stk_addr=%zx stk_size=%zx "
210214
"tls_addr=%zx tls_size=%zx\n",
@@ -250,7 +254,7 @@ void ThreadFinish(ThreadState *thr) {
250254
// Save from info about the thread.
251255
tctx->dead_info = new(internal_alloc(MBlockDeadInfo, sizeof(ThreadDeadInfo)))
252256
ThreadDeadInfo();
253-
for (int i = 0; i < kTraceParts; i++) {
257+
for (uptr i = 0; i < TraceParts(); i++) {
254258
tctx->dead_info->trace.headers[i].epoch0 = thr->trace.headers[i].epoch0;
255259
tctx->dead_info->trace.headers[i].stack0.CopyFrom(
256260
thr->trace.headers[i].stack0);

0 commit comments

Comments
 (0)