thr->fast_state.SetHistorySize(flags()->history_size);
const uptr trace = (epoch0 / kTracePartSize) % TraceParts();
Trace *thr_trace = ThreadTrace(thr->tid);
- thr_trace->headers[trace].epoch0 = epoch0;
+ TraceHeader *hdr = &thr_trace->headers[trace];
+ hdr->epoch0 = epoch0;
+ ObtainCurrentStack(thr, 0, &hdr->stack0);
+ hdr->mset0 = thr->mset;
StatInc(thr, StatSyncAcquire);
sync.Reset(&thr->clock_cache);
DPrintf("#%d: ThreadStart epoch=%zu stk_addr=%zx stk_size=%zx "
--- /dev/null
+// RUN: %clangxx_tsan -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s
+#include <pthread.h>
+#include <stdio.h>
+#include <unistd.h>
+
+int Global;
+volatile int x;
+const int kSize = 64 << 10;
+volatile long data[kSize];
+
+void __attribute__((noinline)) foo() {
+ for (int i = 0; i < kSize; i++)
+ data[i]++;
+}
+
+void *Thread(void *a) {
+ __atomic_store_n(&x, 1, __ATOMIC_RELEASE);
+ foo();
+ data[0]++;
+ return 0;
+}
+
+int main() {
+ for (int i = 0; i < 50; i++) {
+ pthread_t t;
+ pthread_create(&t, 0, Thread, 0);
+ pthread_join(t, 0);
+ }
+ pthread_t t;
+ pthread_create(&t, 0, Thread, 0);
+ sleep(5);
+ for (int i = 0; i < kSize; i++)
+ data[i]++;
+ pthread_join(t, 0);
+ fprintf(stderr, "DONE\n");
+ return 0;
+}
+
+// Previously this test produced bogus stack traces like:
+// Previous write of size 8 at 0x0000006a8ff8 by thread T17:
+// #0 foo() restore_stack.cc:13:5 (restore_stack.cc.exe+0x00000040622c)
+// #1 Thread(void*) restore_stack.cc:18:3 (restore_stack.cc.exe+0x000000406283)
+// #2 __tsan_thread_start_func rtl/tsan_interceptors.cc:886 (restore_stack.cc.exe+0x00000040a749)
+// #3 Thread(void*) restore_stack.cc:18:3 (restore_stack.cc.exe+0x000000406283)
+
+// CHECK: WARNING: ThreadSanitizer: data race
+// CHECK-NOT: __tsan_thread_start_func
+// CHECK-NOT: #3 Thread
+// CHECK: DONE