forked from OSchip/llvm-project
tsan: say what thread had created a thread in reports
llvm-svn: 170346
This commit is contained in:
parent
459e35c261
commit
09b0dbfaf9
|
@ -42,6 +42,6 @@ int main() {
|
|||
// CHECK: #1 alloc
|
||||
// CHECK: #2 AllocThread
|
||||
// ...
|
||||
// CHECK: Thread T1 (tid={{.*}}, finished) created at:
|
||||
// CHECK: Thread T1 (tid={{.*}}, finished) created by main thread at:
|
||||
// CHECK: #0 pthread_create
|
||||
// CHECK: #1 main
|
||||
|
|
|
@ -38,6 +38,6 @@ int main() {
|
|||
// CHECK: Previous write of size 4 at {{.*}} by thread T1:
|
||||
// CHECK: #0 foobar
|
||||
// CHECK: #1 Thread1
|
||||
// CHECK: Thread T1 (tid={{.*}}, finished) created at:
|
||||
// CHECK: Thread T1 (tid={{.*}}, finished) created by main thread at:
|
||||
// CHECK: #0 pthread_create
|
||||
// CHECK: #1 main
|
||||
|
|
|
@ -56,11 +56,11 @@ int main() {
|
|||
// CHECK-NEXT: #0 foo2{{.*}} {{.*}}simple_stack.c:18{{(:26)?}} ({{.*}})
|
||||
// CHECK-NEXT: #1 bar2{{.*}} {{.*}}simple_stack.c:23{{(:3)?}} ({{.*}})
|
||||
// CHECK-NEXT: #2 Thread2{{.*}} {{.*}}simple_stack.c:33{{(:3)?}} ({{.*}})
|
||||
// CHECK: Thread T1 (tid={{.*}}, running) created at:
|
||||
// CHECK: Thread T1 (tid={{.*}}, running) created by main thread at:
|
||||
// CHECK-NEXT: #0 pthread_create {{.*}} ({{.*}})
|
||||
// CHECK-NEXT: #1 StartThread{{.*}} {{.*}}simple_stack.c:38{{(:3)?}} ({{.*}})
|
||||
// CHECK-NEXT: #2 main{{.*}} {{.*}}simple_stack.c:43{{(:3)?}} ({{.*}})
|
||||
// CHECK: Thread T2 ({{.*}}) created at:
|
||||
// CHECK: Thread T2 ({{.*}}) created by main thread at:
|
||||
// CHECK-NEXT: #0 pthread_create {{.*}} ({{.*}})
|
||||
// CHECK-NEXT: #1 StartThread{{.*}} {{.*}}simple_stack.c:38{{(:3)?}} ({{.*}})
|
||||
// CHECK-NEXT: #2 main{{.*}} {{.*}}simple_stack.c:44{{(:3)?}} ({{.*}})
|
||||
|
|
|
@ -35,6 +35,14 @@ ReportDesc::~ReportDesc() {
|
|||
|
||||
#ifndef TSAN_GO
|
||||
|
||||
const int kThreadBufSize = 32;
|
||||
const char *thread_name(char *buf, int tid) {
|
||||
if (tid == 0)
|
||||
return "main thread";
|
||||
internal_snprintf(buf, kThreadBufSize, "thread T%d", tid);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void PrintHeader(ReportType typ) {
|
||||
Printf("WARNING: ThreadSanitizer: ");
|
||||
|
||||
|
@ -82,14 +90,12 @@ static void PrintMutexSet(Vector<ReportMopMutex> const& mset) {
|
|||
}
|
||||
|
||||
static void PrintMop(const ReportMop *mop, bool first) {
|
||||
Printf(" %s of size %d at %p",
|
||||
char thrbuf[kThreadBufSize];
|
||||
Printf(" %s of size %d at %p by %s",
|
||||
(first ? (mop->write ? "Write" : "Read")
|
||||
: (mop->write ? "Previous write" : "Previous read")),
|
||||
mop->size, (void*)mop->addr);
|
||||
if (mop->tid == 0)
|
||||
Printf(" by main thread");
|
||||
else
|
||||
Printf(" by thread T%d", mop->tid);
|
||||
mop->size, (void*)mop->addr,
|
||||
thread_name(thrbuf, mop->tid));
|
||||
PrintMutexSet(mop->mset);
|
||||
Printf(":\n");
|
||||
PrintStack(mop->stack);
|
||||
|
@ -101,12 +107,9 @@ static void PrintLocation(const ReportLocation *loc) {
|
|||
loc->name, loc->size, loc->addr, loc->file, loc->line,
|
||||
loc->module, loc->offset);
|
||||
} else if (loc->type == ReportLocationHeap) {
|
||||
Printf(" Location is heap block of size %zu at %p allocated",
|
||||
loc->size, loc->addr);
|
||||
if (loc->tid == 0)
|
||||
Printf(" by main thread:\n");
|
||||
else
|
||||
Printf(" by thread T%d:\n", loc->tid);
|
||||
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 thread T%d:\n\n", loc->tid);
|
||||
|
@ -128,9 +131,12 @@ static void PrintThread(const ReportThread *rt) {
|
|||
Printf(" Thread T%d", rt->id);
|
||||
if (rt->name)
|
||||
Printf(" '%s'", rt->name);
|
||||
Printf(" (tid=%zu, %s)", rt->pid, rt->running ? "running" : "finished");
|
||||
char thrbuf[kThreadBufSize];
|
||||
Printf(" (tid=%zu, %s) created by %s",
|
||||
rt->pid, rt->running ? "running" : "finished",
|
||||
thread_name(thrbuf, rt->parent_tid));
|
||||
if (rt->stack)
|
||||
Printf(" created at:");
|
||||
Printf(" at:");
|
||||
Printf("\n");
|
||||
PrintStack(rt->stack);
|
||||
}
|
||||
|
|
|
@ -78,6 +78,7 @@ struct ReportThread {
|
|||
uptr pid;
|
||||
bool running;
|
||||
char *name;
|
||||
int parent_tid;
|
||||
ReportStack *stack;
|
||||
};
|
||||
|
||||
|
|
|
@ -377,6 +377,7 @@ struct ThreadContext {
|
|||
u64 epoch0;
|
||||
u64 epoch1;
|
||||
StackTrace creation_stack;
|
||||
int creation_tid;
|
||||
ThreadDeadInfo *dead_info;
|
||||
ThreadContext *dead_next; // In dead thread list.
|
||||
char *name; // As annotated by user.
|
||||
|
|
|
@ -180,6 +180,7 @@ void ScopedReport::AddThread(const ThreadContext *tctx) {
|
|||
rt->pid = tctx->os_id;
|
||||
rt->running = (tctx->status == ThreadStatusRunning);
|
||||
rt->name = tctx->name ? internal_strdup(tctx->name) : 0;
|
||||
rt->parent_tid = tctx->creation_tid;
|
||||
rt->stack = SymbolizeStack(tctx->creation_stack);
|
||||
}
|
||||
|
||||
|
|
|
@ -156,6 +156,7 @@ int ThreadCreate(ThreadState *thr, uptr pc, uptr uid, bool detached) {
|
|||
thr->clock.release(&tctx->sync);
|
||||
StatInc(thr, StatSyncRelease);
|
||||
tctx->creation_stack.ObtainCurrent(thr, pc);
|
||||
tctx->creation_tid = thr->tid;
|
||||
}
|
||||
return tid;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue