Skip to content

Commit a6fa821

Browse files
pudge62maruipu
authored and
maruipu
committed
[tsan] Fix deadlock with dyld during symbolization on darwin platforms
On darwin platforms, callbacks registered via `_dyld_register_func_for_add_image` are invoked with a lock held by dyld. These callbacks, in turn, request locks in the TSan runtime due to instrumented codes or interceptors. Previously, reporting race issues involved holding TSan runtime locks and simultaneously attemping to acquire the dyld lock during symbolization, which leads to deadlock. This commit restructures the reporting process into 3 distinct steps: data collection, symbolization and printing. Each step now only holds the necessary locks to prevent the deadlock.
1 parent 7aabdb8 commit a6fa821

14 files changed

+173
-46
lines changed

compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ bool Symbolizer::SymbolizeData(uptr addr, DataInfo *info) {
108108
&arch))
109109
return false;
110110
info->Clear();
111+
info->start = addr;
111112
info->module = internal_strdup(module_name);
112113
info->module_offset = module_offset;
113114
info->module_arch = arch;

compiler-rt/lib/tsan/go/tsan_go.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,26 @@ ReportLocation *SymbolizeData(uptr addr) {
118118
}
119119
}
120120

121+
bool SymbolizeData(uptr addr, DataInfo *info) {
122+
SymbolizeDataContext cbctx;
123+
internal_memset(&cbctx, 0, sizeof(cbctx));
124+
cbctx.addr = addr;
125+
go_runtime_cb(CallbackSymbolizeData, &cbctx);
126+
if (!cbctx.res)
127+
return false;
128+
if (cbctx.heap) {
129+
return false;
130+
} else {
131+
info->Clear();
132+
info->name = internal_strdup(cbctx.name ? cbctx.name : "??");
133+
info->file = internal_strdup(cbctx.file ? cbctx.file : "??");
134+
info->line = cbctx.line;
135+
info->start = cbctx.start;
136+
info->size = cbctx.size;
137+
return true;
138+
}
139+
}
140+
121141
static ThreadState *main_thr;
122142
static bool inited;
123143

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2069,6 +2069,7 @@ static void ReportErrnoSpoiling(ThreadState *thr, uptr pc, int sig) {
20692069
rep.SetSigNum(sig);
20702070
if (!IsFiredSuppression(ctx, ReportTypeErrnoInSignal, stack)) {
20712071
rep.AddStack(stack, true);
2072+
rep.SymbolizeReport();
20722073
OutputReport(thr, rep);
20732074
}
20742075
}

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.SymbolizeReport();
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.SymbolizeReport();
188189
OutputReport(thr, rep);
189190
}
190191

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "sanitizer_common/sanitizer_thread_registry.h"
1717
#include "sanitizer_common/sanitizer_vector.h"
1818
#include "tsan_defs.h"
19+
#include "tsan_stack_trace.h"
1920

2021
namespace __tsan {
2122

@@ -39,6 +40,7 @@ enum ReportType {
3940
};
4041

4142
struct ReportStack {
43+
VarSizeStackTrace raw;
4244
SymbolizedStack *frames = nullptr;
4345
bool suppressable = false;
4446
};

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,7 @@ uptr TagFromShadowStackFrame(uptr pc);
406406

407407
class ScopedReportBase {
408408
public:
409+
void SetKindAndTag(ReportType typ, uptr tag);
409410
void AddMemoryAccess(uptr addr, uptr external_tag, Shadow s, Tid tid,
410411
StackTrace stack, const MutexSet *mset);
411412
void AddStack(StackTrace stack, bool suppressable = false);
@@ -418,24 +419,24 @@ class ScopedReportBase {
418419
void SetCount(int count);
419420
void SetSigNum(int sig);
420421

422+
void SymbolizeReport();
421423
const ReportDesc *GetReport() const;
422424

423425
protected:
426+
ScopedReportBase();
424427
ScopedReportBase(ReportType typ, uptr tag);
425428
~ScopedReportBase();
426429

427430
private:
428431
ReportDesc *rep_;
429-
// Symbolizer makes lots of intercepted calls. If we try to process them,
430-
// at best it will cause deadlocks on internal mutexes.
431-
ScopedIgnoreInterceptors ignore_interceptors_;
432432

433433
ScopedReportBase(const ScopedReportBase &) = delete;
434434
void operator=(const ScopedReportBase &) = delete;
435435
};
436436

437437
class ScopedReport : public ScopedReportBase {
438438
public:
439+
explicit ScopedReport();
439440
explicit ScopedReport(ReportType typ, uptr tag = kExternalTagNone);
440441
~ScopedReport();
441442

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

Lines changed: 3 additions & 0 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.SymbolizeReport();
6566
OutputReport(thr, rep);
6667
}
6768

@@ -548,6 +549,7 @@ void ReportDeadlock(ThreadState *thr, uptr pc, DDReport *r) {
548549
}
549550
}
550551
}
552+
rep.SymbolizeReport();
551553
OutputReport(thr, rep);
552554
}
553555

@@ -572,6 +574,7 @@ void ReportDestroyLocked(ThreadState *thr, uptr pc, uptr addr,
572574
return;
573575
rep.AddStack(trace, true);
574576
rep.AddLocation(addr, 1);
577+
rep.SymbolizeReport();
575578
OutputReport(thr, rep);
576579
}
577580

0 commit comments

Comments
 (0)