diff options
Diffstat (limited to 'lib/tsan/rtl/tsan_report.cc')
-rw-r--r-- | lib/tsan/rtl/tsan_report.cc | 74 |
1 files changed, 53 insertions, 21 deletions
diff --git a/lib/tsan/rtl/tsan_report.cc b/lib/tsan/rtl/tsan_report.cc index 056dc97387b90..c95c5c86be69c 100644 --- a/lib/tsan/rtl/tsan_report.cc +++ b/lib/tsan/rtl/tsan_report.cc @@ -22,7 +22,8 @@ ReportDesc::ReportDesc() , locs(MBlockReportLoc) , mutexes(MBlockReportMutex) , threads(MBlockReportThread) - , sleep() { + , sleep() + , count() { } ReportMop::ReportMop() @@ -43,23 +44,22 @@ const char *thread_name(char *buf, int tid) { return buf; } -static void PrintHeader(ReportType typ) { - Printf("WARNING: ThreadSanitizer: "); - +static const char *ReportTypeString(ReportType typ) { if (typ == ReportTypeRace) - Printf("data race"); - else if (typ == ReportTypeUseAfterFree) - Printf("heap-use-after-free"); - else if (typ == ReportTypeThreadLeak) - Printf("thread leak"); - else if (typ == ReportTypeMutexDestroyLocked) - Printf("destroy of a locked mutex"); - else if (typ == ReportTypeSignalUnsafe) - Printf("signal-unsafe call inside of a signal"); - else if (typ == ReportTypeErrnoInSignal) - Printf("signal handler spoils errno"); - - Printf(" (pid=%d)\n", GetPid()); + return "data race"; + if (typ == ReportTypeVptrRace) + return "data race on vptr (ctor/dtor vs virtual call)"; + if (typ == ReportTypeUseAfterFree) + return "heap-use-after-free"; + if (typ == ReportTypeThreadLeak) + return "thread leak"; + if (typ == ReportTypeMutexDestroyLocked) + return "destroy of a locked mutex"; + if (typ == ReportTypeSignalUnsafe) + return "signal-unsafe call inside of a signal"; + if (typ == ReportTypeErrnoInSignal) + return "signal handler spoils errno"; + return ""; } void PrintStack(const ReportStack *ent) { @@ -89,11 +89,17 @@ static void PrintMutexSet(Vector<ReportMopMutex> const& mset) { } } +static const char *MopDesc(bool first, bool write, bool atomic) { + return atomic ? (first ? (write ? "Atomic write" : "Atomic read") + : (write ? "Previous atomic write" : "Previous atomic read")) + : (first ? (write ? "Write" : "Read") + : (write ? "Previous write" : "Previous read")); +} + static void PrintMop(const ReportMop *mop, bool first) { char thrbuf[kThreadBufSize]; Printf(" %s of size %d at %p by %s", - (first ? (mop->write ? "Write" : "Read") - : (mop->write ? "Previous write" : "Previous read")), + MopDesc(first, mop->write, mop->atomic), mop->size, (void*)mop->addr, thread_name(thrbuf, mop->tid)); PrintMutexSet(mop->mset); @@ -135,7 +141,7 @@ static void PrintThread(const ReportThread *rt) { if (rt->id == 0) // Little sense in describing the main thread. return; Printf(" Thread T%d", rt->id); - if (rt->name) + if (rt->name && rt->name[0] != '\0') Printf(" '%s'", rt->name); char thrbuf[kThreadBufSize]; Printf(" (tid=%zu, %s) created by %s", @@ -152,9 +158,29 @@ static void PrintSleep(const ReportStack *s) { PrintStack(s); } +static ReportStack *ChooseSummaryStack(const ReportDesc *rep) { + if (rep->mops.Size()) + return rep->mops[0]->stack; + if (rep->stacks.Size()) + return rep->stacks[0]; + if (rep->mutexes.Size()) + return rep->mutexes[0]->stack; + if (rep->threads.Size()) + return rep->threads[0]->stack; + return 0; +} + +ReportStack *SkipTsanInternalFrames(ReportStack *ent) { + while (FrameIsInternal(ent) && ent->next) + ent = ent->next; + return ent; +} + void PrintReport(const ReportDesc *rep) { Printf("==================\n"); - PrintHeader(rep->typ); + const char *rep_typ_str = ReportTypeString(rep->typ); + Printf("WARNING: ThreadSanitizer: %s (pid=%d)\n", rep_typ_str, + (int)internal_getpid()); for (uptr i = 0; i < rep->stacks.Size(); i++) { if (i) @@ -177,6 +203,12 @@ void PrintReport(const ReportDesc *rep) { for (uptr i = 0; i < rep->threads.Size(); i++) PrintThread(rep->threads[i]); + if (rep->typ == ReportTypeThreadLeak && rep->count > 1) + Printf(" And %d more similar thread leaks.\n\n", rep->count - 1); + + if (ReportStack *ent = SkipTsanInternalFrames(ChooseSummaryStack(rep))) + ReportErrorSummary(rep_typ_str, ent->file, ent->line, ent->func); + Printf("==================\n"); } |