Skip to content

Commit a178c06

Browse files
authored
[tsan] Don't symbolize stack traces if dl_iterate_phdr is not ready (#143199)
When a CHECK() fails during TSan initialization, it may segfault (e.g., google/sanitizers#837 (comment)). This is because a failed CHECK() will attempt to print a symbolized stack trace, which requires dl_iterate_phdr, but the interceptor may not yet be set up. This patch fixes the issue by not symbolizing the stack trace if the dl_iterate_phdr interceptor is not ready.
1 parent 4ed0ff8 commit a178c06

File tree

4 files changed

+22
-1
lines changed

4 files changed

+22
-1
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3085,6 +3085,10 @@ void InitializeInterceptors() {
30853085
#if !SANITIZER_ANDROID
30863086
TSAN_INTERCEPT(dl_iterate_phdr);
30873087
#endif
3088+
3089+
// Symbolization indirectly calls dl_iterate_phdr
3090+
ready_to_symbolize = true;
3091+
30883092
TSAN_MAYBE_INTERCEPT_ON_EXIT;
30893093
TSAN_INTERCEPT(__cxa_atexit);
30903094
TSAN_INTERCEPT(_exit);

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,12 @@ void CheckUnwind() {
679679

680680
bool is_initialized;
681681

682+
// Symbolization indirectly calls dl_iterate_phdr. If a CHECK() fails early on
683+
// (prior to the dl_iterate_phdr interceptor setup), resulting in an attempted
684+
// symbolization, it will segfault.
685+
// dl_iterate_phdr is not intercepted for Android.
686+
bool ready_to_symbolize = SANITIZER_ANDROID;
687+
682688
void Initialize(ThreadState *thr) {
683689
// Thread safe because done before all threads exist.
684690
if (is_initialized)

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@
5454

5555
namespace __tsan {
5656

57+
extern bool ready_to_symbolize;
58+
5759
#if !SANITIZER_GO
5860
struct MapUnmapCallback;
5961
# if defined(__mips64) || defined(__aarch64__) || defined(__loongarch__) || \

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -846,7 +846,16 @@ ALWAYS_INLINE USED void PrintCurrentStack(uptr pc, bool fast) {
846846
ptrace->trace_buffer[i] = ptrace->trace_buffer[ptrace->size - i - 1];
847847
ptrace->trace_buffer[ptrace->size - i - 1] = tmp;
848848
}
849-
PrintStack(SymbolizeStack(*ptrace));
849+
850+
if (ready_to_symbolize) {
851+
PrintStack(SymbolizeStack(*ptrace));
852+
} else {
853+
Printf(
854+
"WARNING: PrintCurrentStack() has been called too early, before "
855+
"symbolization is possible. Printing unsymbolized stack trace:\n");
856+
for (unsigned int i = 0; i < ptrace->size; i++)
857+
Printf(" #%u: 0x%zx\n", i, ptrace->trace[i]);
858+
}
850859
#endif
851860
}
852861

0 commit comments

Comments
 (0)