[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., 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, 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.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -54,6 +54,8 @@
|
||||
|
||||
namespace __tsan {
|
||||
|
||||
extern bool ready_to_symbolize;
|
||||
|
||||
#if !SANITIZER_GO
|
||||
struct MapUnmapCallback;
|
||||
# if defined(__mips64) || defined(__aarch64__) || defined(__loongarch__) || \
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user