[llvm] [BOLT] Keep instrumentation diagnostics out of line (PR #225986)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 23 18:21:09 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-bolt
Author: Ilias (iliasabk)
<details>
<summary>Changes</summary>
The instrumentation runtime's diagnostics reserve a 32 KiB scratch buffer on the stack. When `assert()` or `reportNumber()` get inlined into callers on instrumented code paths, the buffer inflates every caller frame — on small thread stacks a single such frame already overflows the guard region and the profiled binary segfaults even when no assertion fires.
Move the `assert()` failure path into a `noinline` helper (`reportAssertFailure`) and mark `reportNumber()` `noinline` as well, so the scratch buffer is only reserved when a diagnostic is actually emitted. This matches the fix sketched in the issue report.
Verified: `common.h` syntax-checks clean in the freestanding runtime build; the only behavioral change is where the buffer lives.
Fixes #<!-- -->225479
---
Full diff: https://github.com/llvm/llvm-project/pull/225986.diff
1 Files Affected:
- (modified) bolt/runtime/common.h (+13-3)
``````````diff
diff --git a/bolt/runtime/common.h b/bolt/runtime/common.h
index 36fb7c89dd7db..208c1feda4995 100644
--- a/bolt/runtime/common.h
+++ b/bolt/runtime/common.h
@@ -235,6 +235,10 @@ void *strStr(const char *const Haystack, const char *const Needle) {
return nullptr;
}
+// Diagnostic helpers allocate a large on-stack scratch buffer. Keep them
+// out of line: if inlined, the buffer is reserved in every caller frame and
+// can overflow small thread stacks even when the report is never emitted.
+__attribute__((noinline))
void reportNumber(const char *Msg, uint64_t Num, uint32_t Base) {
#if !defined(ANDROID_AARCH64)
char Buf[BufSize];
@@ -326,9 +330,10 @@ void reportError(const char *Msg, uint64_t Size) {
#endif
}
-void assert(bool Assertion, const char *Msg) {
- if (Assertion)
- return;
+// Failure path of assert() kept out of line so its large on-stack buffer is
+// not reserved in every inlined caller frame (see reportNumber above).
+__attribute__((noinline))
+void reportAssertFailure(const char *Msg) {
#if defined(ANDROID_AARCH64)
(void)Msg;
boltHandleFatalAndRecover();
@@ -342,6 +347,11 @@ void assert(bool Assertion, const char *Msg) {
#endif
}
+void assert(bool Assertion, const char *Msg) {
+ if (!Assertion)
+ reportAssertFailure(Msg);
+}
+
#define SIG_BLOCK 0
#define SIG_UNBLOCK 1
#define SIG_SETMASK 2
``````````
</details>
https://github.com/llvm/llvm-project/pull/225986
More information about the llvm-commits
mailing list