[clang] [llvm] [sancov] Introduce optional callback for stack-depth tracking (PR #138323)

Marco Elver via cfe-commits cfe-commits at lists.llvm.org
Sun May 4 14:51:03 PDT 2025


================
@@ -1078,22 +1092,44 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
     Store->setNoSanitizeMetadata();
   }
   if (Options.StackDepth && IsEntryBB && !IsLeafFunc) {
-    // Check stack depth.  If it's the deepest so far, record it.
     Module *M = F.getParent();
-    auto FrameAddrPtr = IRB.CreateIntrinsic(
-        Intrinsic::frameaddress,
-        IRB.getPtrTy(M->getDataLayout().getAllocaAddrSpace()),
-        {Constant::getNullValue(Int32Ty)});
-    auto FrameAddrInt = IRB.CreatePtrToInt(FrameAddrPtr, IntptrTy);
-    auto LowestStack = IRB.CreateLoad(IntptrTy, SanCovLowestStack);
-    auto IsStackLower = IRB.CreateICmpULT(FrameAddrInt, LowestStack);
-    auto ThenTerm = SplitBlockAndInsertIfThen(
-        IsStackLower, &*IP, false,
-        MDBuilder(IRB.getContext()).createUnlikelyBranchWeights());
-    IRBuilder<> ThenIRB(ThenTerm);
-    auto Store = ThenIRB.CreateStore(FrameAddrInt, SanCovLowestStack);
-    LowestStack->setNoSanitizeMetadata();
-    Store->setNoSanitizeMetadata();
+    if (Options.StackDepthCallbackMin) {
+      // In callback mode, only add call when stack depth reaches minimum.
+      const DataLayout &DL = M->getDataLayout();
+      uint32_t EstimatedStackSize = 0;
+
+      // Make an estimate on the stack usage.
+      for (auto &I : F.getEntryBlock()) {
+        if (auto *AI = dyn_cast<AllocaInst>(&I)) {
+          if (AI->isStaticAlloca()) {
+            uint32_t TypeSize = DL.getTypeAllocSize(AI->getAllocatedType());
+            EstimatedStackSize += TypeSize;
+          } else {
+            // Over-estimate dynamic sizes.
+            EstimatedStackSize += 4096;
----------------
melver wrote:

This just seems too arbitrary. Can we do something more reliable? Because if this is used beyond the kernel (where we shouldn't even have all that many VLAs or dynamic allocas left - right?), it's anyone's guess if 4K is even a generous over estimation.

I see several options:
- Make this a cl::opt and not a hard-coded constant. The default should be much larger (8 MiB?), so that even we can't accurately calculate stack size we always get a callback.
- Just give up if we found a dynamic alloca, and always do the callback.

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


More information about the cfe-commits mailing list