From 4a6ba6a392a3b2edbe70a885d4c87e2fa5a1a914 Mon Sep 17 00:00:00 2001 From: Dan Blackwell Date: Fri, 18 Jul 2025 14:47:21 +0100 Subject: [PATCH 1/4] [TSan][compiler-rt] Defer symbolization of Reports to as late as possible --- .../lib/tsan/rtl/tsan_interceptors_posix.cpp | 1 + .../lib/tsan/rtl/tsan_interface_ann.cpp | 1 + compiler-rt/lib/tsan/rtl/tsan_mman.cpp | 1 + compiler-rt/lib/tsan/rtl/tsan_report.h | 13 +++ compiler-rt/lib/tsan/rtl/tsan_rtl.h | 1 + compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cpp | 9 +- compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp | 98 ++++++++++++++++--- compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp | 1 + 8 files changed, 108 insertions(+), 17 deletions(-) diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp index 795e05394d71a..5d05789aaccdd 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp @@ -2146,6 +2146,7 @@ static void ReportErrnoSpoiling(ThreadState *thr, uptr pc, int sig) { rep.SetSigNum(sig); if (!IsFiredSuppression(ctx, ReportTypeErrnoInSignal, stack)) { rep.AddStack(stack, true); + rep.SymbolizeStackElems(); OutputReport(thr, rep); } } diff --git a/compiler-rt/lib/tsan/rtl/tsan_interface_ann.cpp b/compiler-rt/lib/tsan/rtl/tsan_interface_ann.cpp index befd6a369026d..d16fd4cfb00d9 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interface_ann.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_interface_ann.cpp @@ -446,6 +446,7 @@ static void ReportMutexHeldWrongContext(ThreadState *thr, uptr pc) { VarSizeStackTrace trace; ObtainCurrentStack(thr, pc, &trace); rep.AddStack(trace, true); + rep.SymbolizeStackElems(); OutputReport(thr, rep); } diff --git a/compiler-rt/lib/tsan/rtl/tsan_mman.cpp b/compiler-rt/lib/tsan/rtl/tsan_mman.cpp index 0ea83fb3b5982..3a0a6a1a4564f 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_mman.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_mman.cpp @@ -185,6 +185,7 @@ static void SignalUnsafeCall(ThreadState *thr, uptr pc) { ThreadRegistryLock l(&ctx->thread_registry); ScopedReport rep(ReportTypeSignalUnsafe); rep.AddStack(stack, true); + rep.SymbolizeStackElems(); OutputReport(thr, rep); } diff --git a/compiler-rt/lib/tsan/rtl/tsan_report.h b/compiler-rt/lib/tsan/rtl/tsan_report.h index 8975540ddfda2..53bb21964dbba 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_report.h +++ b/compiler-rt/lib/tsan/rtl/tsan_report.h @@ -12,6 +12,8 @@ #ifndef TSAN_REPORT_H #define TSAN_REPORT_H +#include "sanitizer_common/sanitizer_internal_defs.h" +#include "sanitizer_common/sanitizer_stacktrace.h" #include "sanitizer_common/sanitizer_symbolizer.h" #include "sanitizer_common/sanitizer_thread_registry.h" #include "sanitizer_common/sanitizer_vector.h" @@ -56,6 +58,7 @@ struct ReportMop { bool atomic; uptr external_tag; Vector mset; + StackTrace stack_trace; ReportStack *stack; ReportMop(); @@ -79,6 +82,7 @@ struct ReportLocation { int fd = 0; bool fd_closed = false; bool suppressable = false; + StackID stack_id = 0; ReportStack *stack = nullptr; }; @@ -89,15 +93,23 @@ struct ReportThread { ThreadType thread_type; char *name; Tid parent_tid; + StackID stack_id; ReportStack *stack; + bool suppressable; }; struct ReportMutex { int id; uptr addr; + StackID stack_id; ReportStack *stack; }; +struct AddedLocationAddr { + uptr addr; + usize locs_idx; +}; + class ReportDesc { public: ReportType typ; @@ -105,6 +117,7 @@ class ReportDesc { Vector stacks; Vector mops; Vector locs; + Vector added_location_addrs; Vector mutexes; Vector threads; Vector unique_tids; diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h index 46276f20831d0..0d9d3bbf580a3 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h @@ -420,6 +420,7 @@ class ScopedReportBase { void AddSleep(StackID stack_id); void SetCount(int count); void SetSigNum(int sig); + void SymbolizeStackElems(void); const ReportDesc *GetReport() const; diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cpp index 2a8aa1915c9ae..0027589939906 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cpp @@ -62,6 +62,7 @@ static void ReportMutexMisuse(ThreadState *thr, uptr pc, ReportType typ, ObtainCurrentStack(thr, pc, &trace); rep.AddStack(trace, true); rep.AddLocation(addr, 1); + rep.SymbolizeStackElems(); OutputReport(thr, rep); } @@ -539,15 +540,18 @@ void ReportDeadlock(ThreadState *thr, uptr pc, DDReport *r) { for (int i = 0; i < r->n; i++) { for (int j = 0; j < (flags()->second_deadlock_stack ? 2 : 1); j++) { u32 stk = r->loop[i].stk[j]; + StackTrace stack; if (stk && stk != kInvalidStackID) { - rep.AddStack(StackDepotGet(stk), true); + stack = StackDepotGet(stk); } else { // Sometimes we fail to extract the stack trace (FIXME: investigate), // but we should still produce some stack trace in the report. - rep.AddStack(StackTrace(&dummy_pc, 1), true); + stack = StackTrace(&dummy_pc, 1); } + rep.AddStack(stack, true); } } + rep.SymbolizeStackElems(); OutputReport(thr, rep); } @@ -572,6 +576,7 @@ void ReportDestroyLocked(ThreadState *thr, uptr pc, uptr addr, return; rep.AddStack(trace, true); rep.AddLocation(addr, 1); + rep.SymbolizeStackElems(); OutputReport(thr, rep); } diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp index 0820bf1adee43..f0848919694fa 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_common.h" +#include "sanitizer_common/sanitizer_internal_defs.h" #include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_placement_new.h" #include "sanitizer_common/sanitizer_stackdepot.h" @@ -187,10 +188,8 @@ void ScopedReportBase::AddMemoryAccess(uptr addr, uptr external_tag, Shadow s, mop->size = size; mop->write = !(typ & kAccessRead); mop->atomic = typ & kAccessAtomic; - mop->stack = SymbolizeStack(stack); mop->external_tag = external_tag; - if (mop->stack) - mop->stack->suppressable = true; + mop->stack_trace = stack; for (uptr i = 0; i < mset->Size(); i++) { MutexSet::Desc d = mset->Get(i); int id = this->AddMutex(d.addr, d.stack_id); @@ -199,6 +198,80 @@ void ScopedReportBase::AddMemoryAccess(uptr addr, uptr external_tag, Shadow s, } } +void ScopedReportBase::SymbolizeStackElems() { + // symbolize memory ops + for (usize i = 0; i < rep_->mops.Size(); i++) { + ReportMop *mop = rep_->mops[i]; + mop->stack = SymbolizeStack(mop->stack_trace); + if (mop->stack) + mop->stack->suppressable = true; + } + + Vector locs_tmp; + + // Repopulate the locations in the order they were added - take care with + // the added locations + usize locs_idx = 0; + for (usize i = 0; i < rep_->added_location_addrs.Size(); i++) { + AddedLocationAddr *added_loc_addr = &rep_->added_location_addrs[i]; + + for (; locs_idx < added_loc_addr->locs_idx; locs_idx++) { + ReportLocation *loc = rep_->locs[locs_idx]; + loc->stack = SymbolizeStackId(loc->stack_id); + locs_tmp.PushBack(loc); + } + + if (ReportLocation *added_loc = SymbolizeData(added_loc_addr->addr)) { + added_loc->suppressable = true; + locs_tmp.PushBack(added_loc); + } + } + + // Append any remaining locations + for (; locs_idx < rep_->locs.Size(); locs_idx++) { + ReportLocation *loc = rep_->locs[locs_idx]; + loc->stack = SymbolizeStackId(loc->stack_id); + locs_tmp.PushBack(loc); + } + + rep_->locs.Reset(); + for (usize i = 0; i < locs_tmp.Size(); i++) rep_->locs.PushBack(locs_tmp[i]); + + // symbolize locations + for (usize i = 0; i < rep_->locs.Size(); i++) { + ReportLocation *loc = rep_->locs[i]; + loc->stack = SymbolizeStackId(loc->stack_id); + } + + usize offset = 0; + for (usize i = 0; i < rep_->added_location_addrs.Size(); i++) { + struct AddedLocationAddr *added_loc = &rep_->added_location_addrs[i]; + if (ReportLocation *loc = SymbolizeData(added_loc->addr)) { + offset++; + loc->suppressable = true; + rep_->locs[added_loc->locs_idx] = loc; + } + } + + // Check that all locs are populated (no-op in release) + for (usize i = 0; i < rep_->locs.Size(); i++) + CHECK_NE(rep_->locs[i], nullptr); + + // symbolize threads + for (usize i = 0; i < rep_->threads.Size(); i++) { + ReportThread *rt = rep_->threads[i]; + rt->stack = SymbolizeStackId(rt->stack_id); + if (rt->stack) + rt->stack->suppressable = rt->suppressable; + } + + // symbolize mutexes + for (usize i = 0; i < rep_->mutexes.Size(); i++) { + ReportMutex *rm = rep_->mutexes[i]; + rm->stack = SymbolizeStackId(rm->stack_id); + } +} + void ScopedReportBase::AddUniqueTid(Tid unique_tid) { rep_->unique_tids.PushBack(unique_tid); } @@ -216,10 +289,8 @@ void ScopedReportBase::AddThread(const ThreadContext *tctx, bool suppressable) { rt->name = internal_strdup(tctx->name); rt->parent_tid = tctx->parent_tid; rt->thread_type = tctx->thread_type; - rt->stack = 0; - rt->stack = SymbolizeStackId(tctx->creation_stack_id); - if (rt->stack) - rt->stack->suppressable = suppressable; + rt->stack_id = tctx->creation_stack_id; + rt->suppressable = suppressable; } #if !SANITIZER_GO @@ -270,7 +341,7 @@ int ScopedReportBase::AddMutex(uptr addr, StackID creation_stack_id) { rep_->mutexes.PushBack(rm); rm->id = rep_->mutexes.Size() - 1; rm->addr = addr; - rm->stack = SymbolizeStackId(creation_stack_id); + rm->stack_id = creation_stack_id; return rm->id; } @@ -288,7 +359,7 @@ void ScopedReportBase::AddLocation(uptr addr, uptr size) { loc->fd_closed = closed; loc->fd = fd; loc->tid = creat_tid; - loc->stack = SymbolizeStackId(creat_stack); + loc->stack_id = creat_stack; rep_->locs.PushBack(loc); AddThread(creat_tid); return; @@ -310,7 +381,7 @@ void ScopedReportBase::AddLocation(uptr addr, uptr size) { loc->heap_chunk_size = b->siz; loc->external_tag = b->tag; loc->tid = b->tid; - loc->stack = SymbolizeStackId(b->stk); + loc->stack_id = b->stk; rep_->locs.PushBack(loc); AddThread(b->tid); return; @@ -324,11 +395,7 @@ void ScopedReportBase::AddLocation(uptr addr, uptr size) { AddThread(tctx); } #endif - if (ReportLocation *loc = SymbolizeData(addr)) { - loc->suppressable = true; - rep_->locs.PushBack(loc); - return; - } + rep_->added_location_addrs.PushBack({addr, rep_->locs.Size()}); } #if !SANITIZER_GO @@ -819,6 +886,7 @@ void ReportRace(ThreadState *thr, RawShadow *shadow_mem, Shadow cur, Shadow old, s[1].epoch() <= thr->last_sleep_clock.Get(s[1].sid())) rep.AddSleep(thr->last_sleep_stack_id); #endif + rep.SymbolizeStackElems(); OutputReport(thr, rep); } diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp index c6a8fd2acb6a8..36ee7af1fd973 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp @@ -96,6 +96,7 @@ void ThreadFinalize(ThreadState *thr) { ScopedReport rep(ReportTypeThreadLeak); rep.AddThread(leaks[i].tctx, true); rep.SetCount(leaks[i].count); + rep.SymbolizeStackElems(); OutputReport(thr, rep); } #endif From d7cb86ddde8a648679a28da5b2f909bf2b21a47b Mon Sep 17 00:00:00 2001 From: Dan Blackwell Date: Tue, 29 Jul 2025 19:23:00 +0100 Subject: [PATCH 2/4] Fixup - simplify the location symbolizing logic --- compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp | 50 +++++--------------- 1 file changed, 13 insertions(+), 37 deletions(-) diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp index f0848919694fa..f45a1520205ff 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp @@ -207,55 +207,30 @@ void ScopedReportBase::SymbolizeStackElems() { mop->stack->suppressable = true; } - Vector locs_tmp; - - // Repopulate the locations in the order they were added - take care with - // the added locations - usize locs_idx = 0; - for (usize i = 0; i < rep_->added_location_addrs.Size(); i++) { - AddedLocationAddr *added_loc_addr = &rep_->added_location_addrs[i]; - - for (; locs_idx < added_loc_addr->locs_idx; locs_idx++) { - ReportLocation *loc = rep_->locs[locs_idx]; - loc->stack = SymbolizeStackId(loc->stack_id); - locs_tmp.PushBack(loc); - } - - if (ReportLocation *added_loc = SymbolizeData(added_loc_addr->addr)) { - added_loc->suppressable = true; - locs_tmp.PushBack(added_loc); - } - } - - // Append any remaining locations - for (; locs_idx < rep_->locs.Size(); locs_idx++) { - ReportLocation *loc = rep_->locs[locs_idx]; - loc->stack = SymbolizeStackId(loc->stack_id); - locs_tmp.PushBack(loc); - } - - rep_->locs.Reset(); - for (usize i = 0; i < locs_tmp.Size(); i++) rep_->locs.PushBack(locs_tmp[i]); - // symbolize locations for (usize i = 0; i < rep_->locs.Size(); i++) { - ReportLocation *loc = rep_->locs[i]; - loc->stack = SymbolizeStackId(loc->stack_id); + // added locations have a NULL placeholder - don't dereference them + if (ReportLocation *loc = rep_->locs[i]) + loc->stack = SymbolizeStackId(loc->stack_id); } - usize offset = 0; + // symbolize any added locations for (usize i = 0; i < rep_->added_location_addrs.Size(); i++) { - struct AddedLocationAddr *added_loc = &rep_->added_location_addrs[i]; + AddedLocationAddr *added_loc = &rep_->added_location_addrs[i]; if (ReportLocation *loc = SymbolizeData(added_loc->addr)) { - offset++; loc->suppressable = true; rep_->locs[added_loc->locs_idx] = loc; } } - // Check that all locs are populated (no-op in release) + // Filter out any added location placeholders that could not be symbolized + Vector filtered_locs; for (usize i = 0; i < rep_->locs.Size(); i++) - CHECK_NE(rep_->locs[i], nullptr); + if (rep_->locs[i] != nullptr) + filtered_locs.PushBack(rep_->locs[i]); + rep_->locs.Resize(filtered_locs.Size()); + for (usize i = 0; i < filtered_locs.Size(); i++) + rep_->locs[i] = (filtered_locs[i]); // symbolize threads for (usize i = 0; i < rep_->threads.Size(); i++) { @@ -396,6 +371,7 @@ void ScopedReportBase::AddLocation(uptr addr, uptr size) { } #endif rep_->added_location_addrs.PushBack({addr, rep_->locs.Size()}); + rep_->locs.PushBack(nullptr); } #if !SANITIZER_GO From 4b76f89e6b0aa32d837fdd48600066d99dc64a65 Mon Sep 17 00:00:00 2001 From: Dan Blackwell Date: Wed, 30 Jul 2025 14:00:57 +0100 Subject: [PATCH 3/4] Do in-place filtering of added locs, and cache Vector::Size() when looping --- compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp | 25 ++++++++++---------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp index f45a1520205ff..33a98f6973438 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp @@ -200,7 +200,7 @@ void ScopedReportBase::AddMemoryAccess(uptr addr, uptr external_tag, Shadow s, void ScopedReportBase::SymbolizeStackElems() { // symbolize memory ops - for (usize i = 0; i < rep_->mops.Size(); i++) { + for (usize i = 0, size = rep_->mops.Size(); i < size; i++) { ReportMop *mop = rep_->mops[i]; mop->stack = SymbolizeStack(mop->stack_trace); if (mop->stack) @@ -208,14 +208,14 @@ void ScopedReportBase::SymbolizeStackElems() { } // symbolize locations - for (usize i = 0; i < rep_->locs.Size(); i++) { + for (usize i = 0, size = rep_->locs.Size(); i < size; i++) { // added locations have a NULL placeholder - don't dereference them if (ReportLocation *loc = rep_->locs[i]) loc->stack = SymbolizeStackId(loc->stack_id); } // symbolize any added locations - for (usize i = 0; i < rep_->added_location_addrs.Size(); i++) { + for (usize i = 0, size = rep_->added_location_addrs.Size(); i < size; i++) { AddedLocationAddr *added_loc = &rep_->added_location_addrs[i]; if (ReportLocation *loc = SymbolizeData(added_loc->addr)) { loc->suppressable = true; @@ -224,16 +224,17 @@ void ScopedReportBase::SymbolizeStackElems() { } // Filter out any added location placeholders that could not be symbolized - Vector filtered_locs; - for (usize i = 0; i < rep_->locs.Size(); i++) - if (rep_->locs[i] != nullptr) - filtered_locs.PushBack(rep_->locs[i]); - rep_->locs.Resize(filtered_locs.Size()); - for (usize i = 0; i < filtered_locs.Size(); i++) - rep_->locs[i] = (filtered_locs[i]); + usize j = 0; + for (usize i = 0, size = rep_->locs.Size(); i < size; i++) { + if (rep_->locs[i] != nullptr) { + rep_->locs[j] = rep_->locs[i]; + j++; + } + } + rep_->locs.Resize(j); // symbolize threads - for (usize i = 0; i < rep_->threads.Size(); i++) { + for (usize i = 0, size = rep_->threads.Size(); i < size; i++) { ReportThread *rt = rep_->threads[i]; rt->stack = SymbolizeStackId(rt->stack_id); if (rt->stack) @@ -241,7 +242,7 @@ void ScopedReportBase::SymbolizeStackElems() { } // symbolize mutexes - for (usize i = 0; i < rep_->mutexes.Size(); i++) { + for (usize i = 0, size = rep_->mutexes.Size(); i < size; i++) { ReportMutex *rm = rep_->mutexes[i]; rm->stack = SymbolizeStackId(rm->stack_id); } From 0c3539e7bda055a342f21e07ba6df1000336934f Mon Sep 17 00:00:00 2001 From: Dan Blackwell Date: Wed, 30 Jul 2025 14:20:20 +0100 Subject: [PATCH 4/4] Move SymbolizeStackElems into OutputReport --- compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp | 1 - compiler-rt/lib/tsan/rtl/tsan_interface_ann.cpp | 1 - compiler-rt/lib/tsan/rtl/tsan_mman.cpp | 1 - compiler-rt/lib/tsan/rtl/tsan_rtl.h | 2 +- compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cpp | 3 --- compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp | 4 ++-- compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp | 1 - 7 files changed, 3 insertions(+), 10 deletions(-) diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp index 5d05789aaccdd..795e05394d71a 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp @@ -2146,7 +2146,6 @@ static void ReportErrnoSpoiling(ThreadState *thr, uptr pc, int sig) { rep.SetSigNum(sig); if (!IsFiredSuppression(ctx, ReportTypeErrnoInSignal, stack)) { rep.AddStack(stack, true); - rep.SymbolizeStackElems(); OutputReport(thr, rep); } } diff --git a/compiler-rt/lib/tsan/rtl/tsan_interface_ann.cpp b/compiler-rt/lib/tsan/rtl/tsan_interface_ann.cpp index d16fd4cfb00d9..befd6a369026d 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interface_ann.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_interface_ann.cpp @@ -446,7 +446,6 @@ static void ReportMutexHeldWrongContext(ThreadState *thr, uptr pc) { VarSizeStackTrace trace; ObtainCurrentStack(thr, pc, &trace); rep.AddStack(trace, true); - rep.SymbolizeStackElems(); OutputReport(thr, rep); } diff --git a/compiler-rt/lib/tsan/rtl/tsan_mman.cpp b/compiler-rt/lib/tsan/rtl/tsan_mman.cpp index 3a0a6a1a4564f..0ea83fb3b5982 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_mman.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_mman.cpp @@ -185,7 +185,6 @@ static void SignalUnsafeCall(ThreadState *thr, uptr pc) { ThreadRegistryLock l(&ctx->thread_registry); ScopedReport rep(ReportTypeSignalUnsafe); rep.AddStack(stack, true); - rep.SymbolizeStackElems(); OutputReport(thr, rep); } diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h index 0d9d3bbf580a3..0b6d5f088b142 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h @@ -499,7 +499,7 @@ void ForkChildAfter(ThreadState *thr, uptr pc, bool start_thread); void ReportRace(ThreadState *thr, RawShadow *shadow_mem, Shadow cur, Shadow old, AccessType typ); -bool OutputReport(ThreadState *thr, const ScopedReport &srep); +bool OutputReport(ThreadState *thr, ScopedReport &srep); bool IsFiredSuppression(Context *ctx, ReportType type, StackTrace trace); bool IsExpectedReport(uptr addr, uptr size); diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cpp index 0027589939906..2a2bf42c92ecb 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cpp @@ -62,7 +62,6 @@ static void ReportMutexMisuse(ThreadState *thr, uptr pc, ReportType typ, ObtainCurrentStack(thr, pc, &trace); rep.AddStack(trace, true); rep.AddLocation(addr, 1); - rep.SymbolizeStackElems(); OutputReport(thr, rep); } @@ -551,7 +550,6 @@ void ReportDeadlock(ThreadState *thr, uptr pc, DDReport *r) { rep.AddStack(stack, true); } } - rep.SymbolizeStackElems(); OutputReport(thr, rep); } @@ -576,7 +574,6 @@ void ReportDestroyLocked(ThreadState *thr, uptr pc, uptr addr, return; rep.AddStack(trace, true); rep.AddLocation(addr, 1); - rep.SymbolizeStackElems(); OutputReport(thr, rep); } diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp index 33a98f6973438..e6f0fda9c72af 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp @@ -672,11 +672,12 @@ static bool HandleRacyStacks(ThreadState *thr, VarSizeStackTrace traces[2]) { return false; } -bool OutputReport(ThreadState *thr, const ScopedReport &srep) { +bool OutputReport(ThreadState *thr, ScopedReport &srep) { // These should have been checked in ShouldReport. // It's too late to check them here, we have already taken locks. CHECK(flags()->report_bugs); CHECK(!thr->suppress_reports); + srep.SymbolizeStackElems(); atomic_store_relaxed(&ctx->last_symbolize_time_ns, NanoTime()); const ReportDesc *rep = srep.GetReport(); CHECK_EQ(thr->current_report, nullptr); @@ -863,7 +864,6 @@ void ReportRace(ThreadState *thr, RawShadow *shadow_mem, Shadow cur, Shadow old, s[1].epoch() <= thr->last_sleep_clock.Get(s[1].sid())) rep.AddSleep(thr->last_sleep_stack_id); #endif - rep.SymbolizeStackElems(); OutputReport(thr, rep); } diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp index 36ee7af1fd973..c6a8fd2acb6a8 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp @@ -96,7 +96,6 @@ void ThreadFinalize(ThreadState *thr) { ScopedReport rep(ReportTypeThreadLeak); rep.AddThread(leaks[i].tctx, true); rep.SetCount(leaks[i].count); - rep.SymbolizeStackElems(); OutputReport(thr, rep); } #endif