-
Notifications
You must be signed in to change notification settings - Fork 15.3k
[tsan] Don't symbolize stack traces if dl_iterate_phdr is not ready #143199
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…eady When a CHECK() fails before TSan is fully initialized, 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, 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.
|
@llvm/pr-subscribers-compiler-rt-sanitizer Author: Thurston Dang (thurstond) ChangesWhen 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, for which 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. Full diff: https://github.com/llvm/llvm-project/pull/143199.diff 4 Files Affected:
diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
index 7c4d23a6a0d74..a4bc3d6cff91a 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp
@@ -3085,6 +3085,10 @@ void InitializeInterceptors() {
#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..d8be21284b934 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_rtl.cpp
@@ -679,6 +679,12 @@ void CheckUnwind() {
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
}
|
…lvm#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.
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, for which 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.