Skip to content

Commit 4a6ba6a

Browse files
committed
[TSan][compiler-rt] Defer symbolization of Reports to as late as possible
1 parent a749e68 commit 4a6ba6a

File tree

8 files changed

+108
-17
lines changed

8 files changed

+108
-17
lines changed

compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2146,6 +2146,7 @@ static void ReportErrnoSpoiling(ThreadState *thr, uptr pc, int sig) {
21462146
rep.SetSigNum(sig);
21472147
if (!IsFiredSuppression(ctx, ReportTypeErrnoInSignal, stack)) {
21482148
rep.AddStack(stack, true);
2149+
rep.SymbolizeStackElems();
21492150
OutputReport(thr, rep);
21502151
}
21512152
}

compiler-rt/lib/tsan/rtl/tsan_interface_ann.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,7 @@ static void ReportMutexHeldWrongContext(ThreadState *thr, uptr pc) {
446446
VarSizeStackTrace trace;
447447
ObtainCurrentStack(thr, pc, &trace);
448448
rep.AddStack(trace, true);
449+
rep.SymbolizeStackElems();
449450
OutputReport(thr, rep);
450451
}
451452

compiler-rt/lib/tsan/rtl/tsan_mman.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ static void SignalUnsafeCall(ThreadState *thr, uptr pc) {
185185
ThreadRegistryLock l(&ctx->thread_registry);
186186
ScopedReport rep(ReportTypeSignalUnsafe);
187187
rep.AddStack(stack, true);
188+
rep.SymbolizeStackElems();
188189
OutputReport(thr, rep);
189190
}
190191

compiler-rt/lib/tsan/rtl/tsan_report.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#ifndef TSAN_REPORT_H
1313
#define TSAN_REPORT_H
1414

15+
#include "sanitizer_common/sanitizer_internal_defs.h"
16+
#include "sanitizer_common/sanitizer_stacktrace.h"
1517
#include "sanitizer_common/sanitizer_symbolizer.h"
1618
#include "sanitizer_common/sanitizer_thread_registry.h"
1719
#include "sanitizer_common/sanitizer_vector.h"
@@ -56,6 +58,7 @@ struct ReportMop {
5658
bool atomic;
5759
uptr external_tag;
5860
Vector<ReportMopMutex> mset;
61+
StackTrace stack_trace;
5962
ReportStack *stack;
6063

6164
ReportMop();
@@ -79,6 +82,7 @@ struct ReportLocation {
7982
int fd = 0;
8083
bool fd_closed = false;
8184
bool suppressable = false;
85+
StackID stack_id = 0;
8286
ReportStack *stack = nullptr;
8387
};
8488

@@ -89,22 +93,31 @@ struct ReportThread {
8993
ThreadType thread_type;
9094
char *name;
9195
Tid parent_tid;
96+
StackID stack_id;
9297
ReportStack *stack;
98+
bool suppressable;
9399
};
94100

95101
struct ReportMutex {
96102
int id;
97103
uptr addr;
104+
StackID stack_id;
98105
ReportStack *stack;
99106
};
100107

108+
struct AddedLocationAddr {
109+
uptr addr;
110+
usize locs_idx;
111+
};
112+
101113
class ReportDesc {
102114
public:
103115
ReportType typ;
104116
uptr tag;
105117
Vector<ReportStack*> stacks;
106118
Vector<ReportMop*> mops;
107119
Vector<ReportLocation*> locs;
120+
Vector<AddedLocationAddr> added_location_addrs;
108121
Vector<ReportMutex*> mutexes;
109122
Vector<ReportThread*> threads;
110123
Vector<Tid> unique_tids;

compiler-rt/lib/tsan/rtl/tsan_rtl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,7 @@ class ScopedReportBase {
420420
void AddSleep(StackID stack_id);
421421
void SetCount(int count);
422422
void SetSigNum(int sig);
423+
void SymbolizeStackElems(void);
423424

424425
const ReportDesc *GetReport() const;
425426

compiler-rt/lib/tsan/rtl/tsan_rtl_mutex.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ static void ReportMutexMisuse(ThreadState *thr, uptr pc, ReportType typ,
6262
ObtainCurrentStack(thr, pc, &trace);
6363
rep.AddStack(trace, true);
6464
rep.AddLocation(addr, 1);
65+
rep.SymbolizeStackElems();
6566
OutputReport(thr, rep);
6667
}
6768

@@ -539,15 +540,18 @@ void ReportDeadlock(ThreadState *thr, uptr pc, DDReport *r) {
539540
for (int i = 0; i < r->n; i++) {
540541
for (int j = 0; j < (flags()->second_deadlock_stack ? 2 : 1); j++) {
541542
u32 stk = r->loop[i].stk[j];
543+
StackTrace stack;
542544
if (stk && stk != kInvalidStackID) {
543-
rep.AddStack(StackDepotGet(stk), true);
545+
stack = StackDepotGet(stk);
544546
} else {
545547
// Sometimes we fail to extract the stack trace (FIXME: investigate),
546548
// but we should still produce some stack trace in the report.
547-
rep.AddStack(StackTrace(&dummy_pc, 1), true);
549+
stack = StackTrace(&dummy_pc, 1);
548550
}
551+
rep.AddStack(stack, true);
549552
}
550553
}
554+
rep.SymbolizeStackElems();
551555
OutputReport(thr, rep);
552556
}
553557

@@ -572,6 +576,7 @@ void ReportDestroyLocked(ThreadState *thr, uptr pc, uptr addr,
572576
return;
573577
rep.AddStack(trace, true);
574578
rep.AddLocation(addr, 1);
579+
rep.SymbolizeStackElems();
575580
OutputReport(thr, rep);
576581
}
577582

compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp

Lines changed: 83 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "sanitizer_common/sanitizer_common.h"
14+
#include "sanitizer_common/sanitizer_internal_defs.h"
1415
#include "sanitizer_common/sanitizer_libc.h"
1516
#include "sanitizer_common/sanitizer_placement_new.h"
1617
#include "sanitizer_common/sanitizer_stackdepot.h"
@@ -187,10 +188,8 @@ void ScopedReportBase::AddMemoryAccess(uptr addr, uptr external_tag, Shadow s,
187188
mop->size = size;
188189
mop->write = !(typ & kAccessRead);
189190
mop->atomic = typ & kAccessAtomic;
190-
mop->stack = SymbolizeStack(stack);
191191
mop->external_tag = external_tag;
192-
if (mop->stack)
193-
mop->stack->suppressable = true;
192+
mop->stack_trace = stack;
194193
for (uptr i = 0; i < mset->Size(); i++) {
195194
MutexSet::Desc d = mset->Get(i);
196195
int id = this->AddMutex(d.addr, d.stack_id);
@@ -199,6 +198,80 @@ void ScopedReportBase::AddMemoryAccess(uptr addr, uptr external_tag, Shadow s,
199198
}
200199
}
201200

201+
void ScopedReportBase::SymbolizeStackElems() {
202+
// symbolize memory ops
203+
for (usize i = 0; i < rep_->mops.Size(); i++) {
204+
ReportMop *mop = rep_->mops[i];
205+
mop->stack = SymbolizeStack(mop->stack_trace);
206+
if (mop->stack)
207+
mop->stack->suppressable = true;
208+
}
209+
210+
Vector<ReportLocation *> locs_tmp;
211+
212+
// Repopulate the locations in the order they were added - take care with
213+
// the added locations
214+
usize locs_idx = 0;
215+
for (usize i = 0; i < rep_->added_location_addrs.Size(); i++) {
216+
AddedLocationAddr *added_loc_addr = &rep_->added_location_addrs[i];
217+
218+
for (; locs_idx < added_loc_addr->locs_idx; locs_idx++) {
219+
ReportLocation *loc = rep_->locs[locs_idx];
220+
loc->stack = SymbolizeStackId(loc->stack_id);
221+
locs_tmp.PushBack(loc);
222+
}
223+
224+
if (ReportLocation *added_loc = SymbolizeData(added_loc_addr->addr)) {
225+
added_loc->suppressable = true;
226+
locs_tmp.PushBack(added_loc);
227+
}
228+
}
229+
230+
// Append any remaining locations
231+
for (; locs_idx < rep_->locs.Size(); locs_idx++) {
232+
ReportLocation *loc = rep_->locs[locs_idx];
233+
loc->stack = SymbolizeStackId(loc->stack_id);
234+
locs_tmp.PushBack(loc);
235+
}
236+
237+
rep_->locs.Reset();
238+
for (usize i = 0; i < locs_tmp.Size(); i++) rep_->locs.PushBack(locs_tmp[i]);
239+
240+
// symbolize locations
241+
for (usize i = 0; i < rep_->locs.Size(); i++) {
242+
ReportLocation *loc = rep_->locs[i];
243+
loc->stack = SymbolizeStackId(loc->stack_id);
244+
}
245+
246+
usize offset = 0;
247+
for (usize i = 0; i < rep_->added_location_addrs.Size(); i++) {
248+
struct AddedLocationAddr *added_loc = &rep_->added_location_addrs[i];
249+
if (ReportLocation *loc = SymbolizeData(added_loc->addr)) {
250+
offset++;
251+
loc->suppressable = true;
252+
rep_->locs[added_loc->locs_idx] = loc;
253+
}
254+
}
255+
256+
// Check that all locs are populated (no-op in release)
257+
for (usize i = 0; i < rep_->locs.Size(); i++)
258+
CHECK_NE(rep_->locs[i], nullptr);
259+
260+
// symbolize threads
261+
for (usize i = 0; i < rep_->threads.Size(); i++) {
262+
ReportThread *rt = rep_->threads[i];
263+
rt->stack = SymbolizeStackId(rt->stack_id);
264+
if (rt->stack)
265+
rt->stack->suppressable = rt->suppressable;
266+
}
267+
268+
// symbolize mutexes
269+
for (usize i = 0; i < rep_->mutexes.Size(); i++) {
270+
ReportMutex *rm = rep_->mutexes[i];
271+
rm->stack = SymbolizeStackId(rm->stack_id);
272+
}
273+
}
274+
202275
void ScopedReportBase::AddUniqueTid(Tid unique_tid) {
203276
rep_->unique_tids.PushBack(unique_tid);
204277
}
@@ -216,10 +289,8 @@ void ScopedReportBase::AddThread(const ThreadContext *tctx, bool suppressable) {
216289
rt->name = internal_strdup(tctx->name);
217290
rt->parent_tid = tctx->parent_tid;
218291
rt->thread_type = tctx->thread_type;
219-
rt->stack = 0;
220-
rt->stack = SymbolizeStackId(tctx->creation_stack_id);
221-
if (rt->stack)
222-
rt->stack->suppressable = suppressable;
292+
rt->stack_id = tctx->creation_stack_id;
293+
rt->suppressable = suppressable;
223294
}
224295

225296
#if !SANITIZER_GO
@@ -270,7 +341,7 @@ int ScopedReportBase::AddMutex(uptr addr, StackID creation_stack_id) {
270341
rep_->mutexes.PushBack(rm);
271342
rm->id = rep_->mutexes.Size() - 1;
272343
rm->addr = addr;
273-
rm->stack = SymbolizeStackId(creation_stack_id);
344+
rm->stack_id = creation_stack_id;
274345
return rm->id;
275346
}
276347

@@ -288,7 +359,7 @@ void ScopedReportBase::AddLocation(uptr addr, uptr size) {
288359
loc->fd_closed = closed;
289360
loc->fd = fd;
290361
loc->tid = creat_tid;
291-
loc->stack = SymbolizeStackId(creat_stack);
362+
loc->stack_id = creat_stack;
292363
rep_->locs.PushBack(loc);
293364
AddThread(creat_tid);
294365
return;
@@ -310,7 +381,7 @@ void ScopedReportBase::AddLocation(uptr addr, uptr size) {
310381
loc->heap_chunk_size = b->siz;
311382
loc->external_tag = b->tag;
312383
loc->tid = b->tid;
313-
loc->stack = SymbolizeStackId(b->stk);
384+
loc->stack_id = b->stk;
314385
rep_->locs.PushBack(loc);
315386
AddThread(b->tid);
316387
return;
@@ -324,11 +395,7 @@ void ScopedReportBase::AddLocation(uptr addr, uptr size) {
324395
AddThread(tctx);
325396
}
326397
#endif
327-
if (ReportLocation *loc = SymbolizeData(addr)) {
328-
loc->suppressable = true;
329-
rep_->locs.PushBack(loc);
330-
return;
331-
}
398+
rep_->added_location_addrs.PushBack({addr, rep_->locs.Size()});
332399
}
333400

334401
#if !SANITIZER_GO
@@ -819,6 +886,7 @@ void ReportRace(ThreadState *thr, RawShadow *shadow_mem, Shadow cur, Shadow old,
819886
s[1].epoch() <= thr->last_sleep_clock.Get(s[1].sid()))
820887
rep.AddSleep(thr->last_sleep_stack_id);
821888
#endif
889+
rep.SymbolizeStackElems();
822890
OutputReport(thr, rep);
823891
}
824892

compiler-rt/lib/tsan/rtl/tsan_rtl_thread.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ void ThreadFinalize(ThreadState *thr) {
9696
ScopedReport rep(ReportTypeThreadLeak);
9797
rep.AddThread(leaks[i].tctx, true);
9898
rep.SetCount(leaks[i].count);
99+
rep.SymbolizeStackElems();
99100
OutputReport(thr, rep);
100101
}
101102
#endif

0 commit comments

Comments
 (0)