From 6eaf4632a21aa8ad8ba526b3810a360f0811bcba Mon Sep 17 00:00:00 2001 From: Thurston Dang Date: Fri, 6 Jun 2025 20:06:29 +0000 Subject: [PATCH 1/2] [NFCI][tsan] Don't symbolize stack traces if dl_iterate_phdr is not ready When a CHECK() fails before TSan is fully initialized, it may segfault (e.g., https://github.com/google/sanitizers/issues/837#issuecomment-2939267531). This is because a failed CHECK() will attempt to print a symbolized stack trace, which requires dl_iterate_phdr, for which the interceptor is not yet set up. This patch fixes the issue by not symbolizing the stack trace if the dl_iterate_phdr interceptor is not ready. --- compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp | 5 +++++ compiler-rt/lib/tsan/rtl/tsan_rtl.cpp | 7 +++++++ compiler-rt/lib/tsan/rtl/tsan_rtl.h | 2 ++ compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp | 11 ++++++++++- 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp index 7c4d23a6a0d74..3565e50892ecf 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp @@ -3082,9 +3082,14 @@ void InitializeInterceptors() { #if SANITIZER_LINUX TSAN_INTERCEPT(clone); #endif + #if !SANITIZER_ANDROID TSAN_INTERCEPT(dl_iterate_phdr); #endif + + // Symbolization indirectly calls dl_iterate_phdr + ready_to_symbolize = true; + TSAN_MAYBE_INTERCEPT_ON_EXIT; TSAN_INTERCEPT(__cxa_atexit); TSAN_INTERCEPT(_exit); diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp index c83efec8eaca2..00f113834b4af 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp @@ -673,12 +673,19 @@ void CheckUnwind() { thr->ignore_reads_and_writes++; atomic_store_relaxed(&thr->in_signal_handler, 0); #endif + PrintCurrentStack(StackTrace::GetCurrentPc(), common_flags()->fast_unwind_on_fatal); } bool is_initialized; +// Symbolization indirectly calls dl_iterate_phdr. If a CHECK() fails early on +// (prior to the dl_iterate_phdr interceptor setup), resulting in an attempted +// symbolization, it will segfault. +// dl_iterate_phdr is not intercepted for Android. +bool ready_to_symbolize = SANITIZER_ANDROID; + void Initialize(ThreadState *thr) { // Thread safe because done before all threads exist. if (is_initialized) diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.h b/compiler-rt/lib/tsan/rtl/tsan_rtl.h index 4dc5e630c5249..0be53599b6a49 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.h +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.h @@ -54,6 +54,8 @@ namespace __tsan { +extern bool ready_to_symbolize; + #if !SANITIZER_GO struct MapUnmapCallback; # if defined(__mips64) || defined(__aarch64__) || defined(__loongarch__) || \ diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp index 51a98e2f2d5e7..0820bf1adee43 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cpp @@ -846,7 +846,16 @@ ALWAYS_INLINE USED void PrintCurrentStack(uptr pc, bool fast) { ptrace->trace_buffer[i] = ptrace->trace_buffer[ptrace->size - i - 1]; ptrace->trace_buffer[ptrace->size - i - 1] = tmp; } - PrintStack(SymbolizeStack(*ptrace)); + + if (ready_to_symbolize) { + PrintStack(SymbolizeStack(*ptrace)); + } else { + Printf( + "WARNING: PrintCurrentStack() has been called too early, before " + "symbolization is possible. Printing unsymbolized stack trace:\n"); + for (unsigned int i = 0; i < ptrace->size; i++) + Printf(" #%u: 0x%zx\n", i, ptrace->trace[i]); + } #endif } From 8c705231b843274dd99e7f14255fac9c4dff46a6 Mon Sep 17 00:00:00 2001 From: Thurston Dang Date: Fri, 6 Jun 2025 20:21:15 +0000 Subject: [PATCH 2/2] Revert newlines --- compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp | 1 - compiler-rt/lib/tsan/rtl/tsan_rtl.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp index 3565e50892ecf..a4bc3d6cff91a 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp @@ -3082,7 +3082,6 @@ void InitializeInterceptors() { #if SANITIZER_LINUX TSAN_INTERCEPT(clone); #endif - #if !SANITIZER_ANDROID TSAN_INTERCEPT(dl_iterate_phdr); #endif diff --git a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp index 00f113834b4af..d8be21284b934 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp @@ -673,7 +673,6 @@ void CheckUnwind() { thr->ignore_reads_and_writes++; atomic_store_relaxed(&thr->in_signal_handler, 0); #endif - PrintCurrentStack(StackTrace::GetCurrentPc(), common_flags()->fast_unwind_on_fatal); }