[compiler-rt] [asan] Reduce stack usage of DescribeThread() (PR #176540)

via llvm-commits llvm-commits at lists.llvm.org
Sat Jan 17 00:17:36 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-compiler-rt-sanitizer

Author: Thurston Dang (thurstond)

<details>
<summary>Changes</summary>

Manually eliminate tail calls, because the compiler didn't.

This fixes some rare crashes (stack overflows) that can occur during ASan's error reporting, if there is a deep nesting structure to thread creation.

---
Full diff: https://github.com/llvm/llvm-project/pull/176540.diff


1 Files Affected:

- (modified) compiler-rt/lib/asan/asan_descriptions.cpp (+34-28) 


``````````diff
diff --git a/compiler-rt/lib/asan/asan_descriptions.cpp b/compiler-rt/lib/asan/asan_descriptions.cpp
index 18c2a6c571c1f..3b51dbc25626e 100644
--- a/compiler-rt/lib/asan/asan_descriptions.cpp
+++ b/compiler-rt/lib/asan/asan_descriptions.cpp
@@ -36,37 +36,43 @@ AsanThreadIdAndName::AsanThreadIdAndName(u32 tid)
   asanThreadRegistry().CheckLocked();
 }
 
+// Prints this thread and, if flags()->print_full_thread_history, its ancestors
 void DescribeThread(AsanThreadContext *context) {
-  CHECK(context);
-  asanThreadRegistry().CheckLocked();
-  // No need to announce the main thread.
-  if (context->tid == kMainTid || context->announced) {
-    return;
-  }
-  context->announced = true;
-
-  InternalScopedString str;
-  str.AppendF("Thread %s", AsanThreadIdAndName(context).c_str());
-
-  AsanThreadContext *parent_context =
-      context->parent_tid == kInvalidTid
-          ? nullptr
-          : GetThreadContextByTidLocked(context->parent_tid);
-
-  // `context->parent_tid` may point to reused slot. Check `unique_id` which
-  // is always smaller for the parent, always greater for a new user.
-  if (!parent_context || context->unique_id <= parent_context->unique_id) {
-    str.Append(" created by unknown thread\n");
+  while (true) {
+    CHECK(context);
+    asanThreadRegistry().CheckLocked();
+    // No need to announce the main thread.
+    if (context->tid == kMainTid || context->announced) {
+      return;
+    }
+    context->announced = true;
+
+    InternalScopedString str;
+    str.AppendF("Thread %s", AsanThreadIdAndName(context).c_str());
+
+    AsanThreadContext* parent_context =
+        context->parent_tid == kInvalidTid
+            ? nullptr
+            : GetThreadContextByTidLocked(context->parent_tid);
+
+    // `context->parent_tid` may point to reused slot. Check `unique_id` which
+    // is always smaller for the parent, always greater for a new user.
+    if (!parent_context || context->unique_id <= parent_context->unique_id) {
+      str.Append(" created by unknown thread\n");
+      Printf("%s", str.data());
+      return;
+    }
+    str.AppendF(" created by %s here:\n",
+                AsanThreadIdAndName(context->parent_tid).c_str());
     Printf("%s", str.data());
-    return;
+    StackDepotGet(context->stack_id).Print();
+
+    // Recursively described parent thread if needed.
+    if (flags()->print_full_thread_history)
+      context = parent_context;
+    else
+      return;
   }
-  str.AppendF(" created by %s here:\n",
-              AsanThreadIdAndName(context->parent_tid).c_str());
-  Printf("%s", str.data());
-  StackDepotGet(context->stack_id).Print();
-  // Recursively described parent thread if needed.
-  if (flags()->print_full_thread_history)
-    DescribeThread(parent_context);
 }
 
 // Shadow descriptions

``````````

</details>


https://github.com/llvm/llvm-project/pull/176540


More information about the llvm-commits mailing list