forked from OSchip/llvm-project
[TSan] Add a runtime flag to print full thread creation stacks up to the main thread
Currently, we only print how threads involved in data race are created from their parent threads. Add a runtime flag 'print_full_thread_history' to print thread creation stacks for the threads involved in the data race and their ancestors up to the main thread. Reviewed By: dvyukov Differential Revision: https://reviews.llvm.org/D122131
This commit is contained in:
parent
f82ec5532b
commit
1d4d2cceda
|
@ -81,3 +81,6 @@ TSAN_FLAG(bool, ignore_noninstrumented_modules, SANITIZER_MAC ? true : false,
|
|||
"modules.")
|
||||
TSAN_FLAG(bool, shared_ptr_interceptor, true,
|
||||
"Track atomic reference counting in libc++ shared_ptr and weak_ptr.")
|
||||
TSAN_FLAG(bool, print_full_thread_history, false,
|
||||
"If set, prints thread creation stacks for the threads involved in "
|
||||
"the report and their ancestors up to the main thread.")
|
||||
|
|
|
@ -823,6 +823,18 @@ void ReportRace(ThreadState *thr, RawShadow *shadow_mem, Shadow cur, Shadow old,
|
|||
|
||||
rep.AddLocation(addr_min, addr_max - addr_min);
|
||||
|
||||
if (flags()->print_full_thread_history) {
|
||||
const ReportDesc *rep_desc = rep.GetReport();
|
||||
for (uptr i = 0; i < rep_desc->threads.Size(); i++) {
|
||||
Tid parent_tid = rep_desc->threads[i]->parent_tid;
|
||||
if (parent_tid == kMainTid || parent_tid == kInvalidTid)
|
||||
continue;
|
||||
ThreadContext *parent_tctx = static_cast<ThreadContext *>(
|
||||
ctx->thread_registry.GetThreadLocked(parent_tid));
|
||||
rep.AddThread(parent_tctx);
|
||||
}
|
||||
}
|
||||
|
||||
#if !SANITIZER_GO
|
||||
if (!((typ0 | typ1) & kAccessFree) &&
|
||||
s[1].epoch() <= thr->last_sleep_clock.Get(s[1].sid()))
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
// RUN: %clangxx_tsan -O1 %s -o %t && %env_tsan_opts=print_full_thread_history=true %deflake %run %t 2>&1 | FileCheck %s
|
||||
|
||||
#include "test.h"
|
||||
|
||||
int Global;
|
||||
|
||||
void *Thread2(void *x) {
|
||||
barrier_wait(&barrier);
|
||||
Global++;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *Thread3(void *x) {
|
||||
Global--;
|
||||
barrier_wait(&barrier);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *Thread1(void *x) {
|
||||
pthread_t t[2];
|
||||
pthread_create(&t[0], NULL, Thread2, NULL);
|
||||
pthread_create(&t[1], NULL, Thread3, NULL);
|
||||
pthread_join(t[0], NULL);
|
||||
pthread_join(t[1], NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main() {
|
||||
barrier_init(&barrier, 2);
|
||||
pthread_t t;
|
||||
pthread_create(&t, NULL, Thread1, NULL);
|
||||
pthread_join(t, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// CHECK: WARNING: ThreadSanitizer: data race
|
||||
// CHECK: Thread T2 {{.*}} created by thread T1 at
|
||||
// CHECK: Thread T3 {{.*}} created by thread T1 at:
|
||||
// CHECK: Thread T1 {{.*}} created by main thread at:
|
||||
// CHECK: SUMMARY: ThreadSanitizer: data race{{.*}}
|
Loading…
Reference in New Issue