-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[sancov] Fix stack-depth tracking to use debug locations #162428
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
@llvm/pr-subscribers-clang Author: Kees Cook (kees) ChangesAs fixed in commits llvm/llvm-project@913f7e9, llvm/llvm-project@4a8b124, and llvm/llvm-project@4eef2e3, also fix the stack-depth tracking code to use InstrumentationIRBuilder, and set the Call's Debug location to EntryLoc. cc @nathanchance @melver @JustinStitt @bwendling Full diff: https://github.com/llvm/llvm-project/pull/162428.diff 2 Files Affected:
diff --git a/clang/test/CodeGen/sanitizer-coverage-stack-depth-debug-loc.c b/clang/test/CodeGen/sanitizer-coverage-stack-depth-debug-loc.c
new file mode 100644
index 0000000000000..33791dabcdca8
--- /dev/null
+++ b/clang/test/CodeGen/sanitizer-coverage-stack-depth-debug-loc.c
@@ -0,0 +1,40 @@
+// Test that SanitizerCoverage preserves debug locations when inserting stack depth tracking
+// This is a regression test for GitHub issue ClangBuiltLinux/linux#2125
+//
+// The bug was that IRBuilder<> was used instead of InstrumentationIRBuilder in SanitizerCoverage,
+// causing inserted instructions to lack !dbg metadata. This caused LTO builds with debug info
+// to fail verification with:
+// "inlinable function call in a function with debug info must have a !dbg location"
+//
+// Test the lowest-stack tracking path (default stack-depth mode)
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s \
+// RUN: -fsanitize-coverage-type=1 -fsanitize-coverage-stack-depth -debug-info-kind=limited \
+// RUN: | FileCheck %s --check-prefix=CHECK-STORE
+//
+// Test the callback path (stack-depth with callback-min threshold)
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s \
+// RUN: -fsanitize-coverage-type=1 -mllvm -sanitizer-coverage-stack-depth \
+// RUN: -mllvm -sanitizer-coverage-stack-depth-callback-min=1 -debug-info-kind=limited \
+// RUN: | FileCheck %s --check-prefix=CHECK-CALLBACK
+//
+// Verify the store to __sancov_lowest_stack has a debug location
+// CHECK-STORE: store i64 %{{.*}}, ptr @__sancov_lowest_stack, align 8, !dbg !{{[0-9]+}}, {{.*}}!nosanitize
+//
+// Verify the call to __sanitizer_cov_stack_depth has a debug location
+// CHECK-CALLBACK: call void @__sanitizer_cov_stack_depth(){{.*}}, !dbg !{{[0-9]+}}
+
+extern void external_func(void);
+
+// Mark as always_inline to ensure the bug condition is met
+__attribute__((always_inline))
+static inline void inline_helper(void) {
+ external_func();
+}
+
+void foo(int a) {
+ int local[4]; // Stack allocation to trigger stack depth tracking
+ if (a > 0) {
+ inline_helper();
+ }
+ local[0] = a;
+}
diff --git a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
index 5b8ea1547ca2f..5dbd0ec2a0e27 100644
--- a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
+++ b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
@@ -1084,7 +1084,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
auto ThenTerm = SplitBlockAndInsertIfThen(
IRB.CreateIsNull(Load), &*IP, false,
MDBuilder(IRB.getContext()).createUnlikelyBranchWeights());
- IRBuilder<> ThenIRB(ThenTerm);
+ InstrumentationIRBuilder ThenIRB(ThenTerm);
auto Store = ThenIRB.CreateStore(ConstantInt::getTrue(Int1Ty), FlagPtr);
Load->setNoSanitizeMetadata();
Store->setNoSanitizeMetadata();
@@ -1131,7 +1131,10 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
EstimatedStackSize >= Options.StackDepthCallbackMin) {
if (InsertBefore)
IRB.SetInsertPoint(InsertBefore);
- IRB.CreateCall(SanCovStackDepthCallback)->setCannotMerge();
+ auto Call = IRB.CreateCall(SanCovStackDepthCallback);
+ if (EntryLoc)
+ Call->setDebugLoc(EntryLoc);
+ Call->setCannotMerge();
}
} else {
// Check stack depth. If it's the deepest so far, record it.
@@ -1144,7 +1147,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
auto ThenTerm = SplitBlockAndInsertIfThen(
IsStackLower, &*IP, false,
MDBuilder(IRB.getContext()).createUnlikelyBranchWeights());
- IRBuilder<> ThenIRB(ThenTerm);
+ InstrumentationIRBuilder ThenIRB(ThenTerm);
auto Store = ThenIRB.CreateStore(FrameAddrInt, SanCovLowestStack);
LowestStack->setNoSanitizeMetadata();
Store->setNoSanitizeMetadata();
|
@llvm/pr-subscribers-llvm-transforms Author: Kees Cook (kees) ChangesAs fixed in commits llvm/llvm-project@913f7e9, llvm/llvm-project@4a8b124, and llvm/llvm-project@4eef2e3, also fix the stack-depth tracking code to use InstrumentationIRBuilder, and set the Call's Debug location to EntryLoc. cc @nathanchance @melver @JustinStitt @bwendling Full diff: https://github.com/llvm/llvm-project/pull/162428.diff 2 Files Affected:
diff --git a/clang/test/CodeGen/sanitizer-coverage-stack-depth-debug-loc.c b/clang/test/CodeGen/sanitizer-coverage-stack-depth-debug-loc.c
new file mode 100644
index 0000000000000..33791dabcdca8
--- /dev/null
+++ b/clang/test/CodeGen/sanitizer-coverage-stack-depth-debug-loc.c
@@ -0,0 +1,40 @@
+// Test that SanitizerCoverage preserves debug locations when inserting stack depth tracking
+// This is a regression test for GitHub issue ClangBuiltLinux/linux#2125
+//
+// The bug was that IRBuilder<> was used instead of InstrumentationIRBuilder in SanitizerCoverage,
+// causing inserted instructions to lack !dbg metadata. This caused LTO builds with debug info
+// to fail verification with:
+// "inlinable function call in a function with debug info must have a !dbg location"
+//
+// Test the lowest-stack tracking path (default stack-depth mode)
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s \
+// RUN: -fsanitize-coverage-type=1 -fsanitize-coverage-stack-depth -debug-info-kind=limited \
+// RUN: | FileCheck %s --check-prefix=CHECK-STORE
+//
+// Test the callback path (stack-depth with callback-min threshold)
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s \
+// RUN: -fsanitize-coverage-type=1 -mllvm -sanitizer-coverage-stack-depth \
+// RUN: -mllvm -sanitizer-coverage-stack-depth-callback-min=1 -debug-info-kind=limited \
+// RUN: | FileCheck %s --check-prefix=CHECK-CALLBACK
+//
+// Verify the store to __sancov_lowest_stack has a debug location
+// CHECK-STORE: store i64 %{{.*}}, ptr @__sancov_lowest_stack, align 8, !dbg !{{[0-9]+}}, {{.*}}!nosanitize
+//
+// Verify the call to __sanitizer_cov_stack_depth has a debug location
+// CHECK-CALLBACK: call void @__sanitizer_cov_stack_depth(){{.*}}, !dbg !{{[0-9]+}}
+
+extern void external_func(void);
+
+// Mark as always_inline to ensure the bug condition is met
+__attribute__((always_inline))
+static inline void inline_helper(void) {
+ external_func();
+}
+
+void foo(int a) {
+ int local[4]; // Stack allocation to trigger stack depth tracking
+ if (a > 0) {
+ inline_helper();
+ }
+ local[0] = a;
+}
diff --git a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
index 5b8ea1547ca2f..5dbd0ec2a0e27 100644
--- a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
+++ b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
@@ -1084,7 +1084,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
auto ThenTerm = SplitBlockAndInsertIfThen(
IRB.CreateIsNull(Load), &*IP, false,
MDBuilder(IRB.getContext()).createUnlikelyBranchWeights());
- IRBuilder<> ThenIRB(ThenTerm);
+ InstrumentationIRBuilder ThenIRB(ThenTerm);
auto Store = ThenIRB.CreateStore(ConstantInt::getTrue(Int1Ty), FlagPtr);
Load->setNoSanitizeMetadata();
Store->setNoSanitizeMetadata();
@@ -1131,7 +1131,10 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
EstimatedStackSize >= Options.StackDepthCallbackMin) {
if (InsertBefore)
IRB.SetInsertPoint(InsertBefore);
- IRB.CreateCall(SanCovStackDepthCallback)->setCannotMerge();
+ auto Call = IRB.CreateCall(SanCovStackDepthCallback);
+ if (EntryLoc)
+ Call->setDebugLoc(EntryLoc);
+ Call->setCannotMerge();
}
} else {
// Check stack depth. If it's the deepest so far, record it.
@@ -1144,7 +1147,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
auto ThenTerm = SplitBlockAndInsertIfThen(
IsStackLower, &*IP, false,
MDBuilder(IRB.getContext()).createUnlikelyBranchWeights());
- IRBuilder<> ThenIRB(ThenTerm);
+ InstrumentationIRBuilder ThenIRB(ThenTerm);
auto Store = ThenIRB.CreateStore(FrameAddrInt, SanCovLowestStack);
LowestStack->setNoSanitizeMetadata();
Store->setNoSanitizeMetadata();
|
@llvm/pr-subscribers-compiler-rt-sanitizer Author: Kees Cook (kees) ChangesAs fixed in commits llvm/llvm-project@913f7e9, llvm/llvm-project@4a8b124, and llvm/llvm-project@4eef2e3, also fix the stack-depth tracking code to use InstrumentationIRBuilder, and set the Call's Debug location to EntryLoc. cc @nathanchance @melver @JustinStitt @bwendling Full diff: https://github.com/llvm/llvm-project/pull/162428.diff 2 Files Affected:
diff --git a/clang/test/CodeGen/sanitizer-coverage-stack-depth-debug-loc.c b/clang/test/CodeGen/sanitizer-coverage-stack-depth-debug-loc.c
new file mode 100644
index 0000000000000..33791dabcdca8
--- /dev/null
+++ b/clang/test/CodeGen/sanitizer-coverage-stack-depth-debug-loc.c
@@ -0,0 +1,40 @@
+// Test that SanitizerCoverage preserves debug locations when inserting stack depth tracking
+// This is a regression test for GitHub issue ClangBuiltLinux/linux#2125
+//
+// The bug was that IRBuilder<> was used instead of InstrumentationIRBuilder in SanitizerCoverage,
+// causing inserted instructions to lack !dbg metadata. This caused LTO builds with debug info
+// to fail verification with:
+// "inlinable function call in a function with debug info must have a !dbg location"
+//
+// Test the lowest-stack tracking path (default stack-depth mode)
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s \
+// RUN: -fsanitize-coverage-type=1 -fsanitize-coverage-stack-depth -debug-info-kind=limited \
+// RUN: | FileCheck %s --check-prefix=CHECK-STORE
+//
+// Test the callback path (stack-depth with callback-min threshold)
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s \
+// RUN: -fsanitize-coverage-type=1 -mllvm -sanitizer-coverage-stack-depth \
+// RUN: -mllvm -sanitizer-coverage-stack-depth-callback-min=1 -debug-info-kind=limited \
+// RUN: | FileCheck %s --check-prefix=CHECK-CALLBACK
+//
+// Verify the store to __sancov_lowest_stack has a debug location
+// CHECK-STORE: store i64 %{{.*}}, ptr @__sancov_lowest_stack, align 8, !dbg !{{[0-9]+}}, {{.*}}!nosanitize
+//
+// Verify the call to __sanitizer_cov_stack_depth has a debug location
+// CHECK-CALLBACK: call void @__sanitizer_cov_stack_depth(){{.*}}, !dbg !{{[0-9]+}}
+
+extern void external_func(void);
+
+// Mark as always_inline to ensure the bug condition is met
+__attribute__((always_inline))
+static inline void inline_helper(void) {
+ external_func();
+}
+
+void foo(int a) {
+ int local[4]; // Stack allocation to trigger stack depth tracking
+ if (a > 0) {
+ inline_helper();
+ }
+ local[0] = a;
+}
diff --git a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
index 5b8ea1547ca2f..5dbd0ec2a0e27 100644
--- a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
+++ b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
@@ -1084,7 +1084,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
auto ThenTerm = SplitBlockAndInsertIfThen(
IRB.CreateIsNull(Load), &*IP, false,
MDBuilder(IRB.getContext()).createUnlikelyBranchWeights());
- IRBuilder<> ThenIRB(ThenTerm);
+ InstrumentationIRBuilder ThenIRB(ThenTerm);
auto Store = ThenIRB.CreateStore(ConstantInt::getTrue(Int1Ty), FlagPtr);
Load->setNoSanitizeMetadata();
Store->setNoSanitizeMetadata();
@@ -1131,7 +1131,10 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
EstimatedStackSize >= Options.StackDepthCallbackMin) {
if (InsertBefore)
IRB.SetInsertPoint(InsertBefore);
- IRB.CreateCall(SanCovStackDepthCallback)->setCannotMerge();
+ auto Call = IRB.CreateCall(SanCovStackDepthCallback);
+ if (EntryLoc)
+ Call->setDebugLoc(EntryLoc);
+ Call->setCannotMerge();
}
} else {
// Check stack depth. If it's the deepest so far, record it.
@@ -1144,7 +1147,7 @@ void ModuleSanitizerCoverage::InjectCoverageAtBlock(Function &F, BasicBlock &BB,
auto ThenTerm = SplitBlockAndInsertIfThen(
IsStackLower, &*IP, false,
MDBuilder(IRB.getContext()).createUnlikelyBranchWeights());
- IRBuilder<> ThenIRB(ThenTerm);
+ InstrumentationIRBuilder ThenIRB(ThenTerm);
auto Store = ThenIRB.CreateStore(FrameAddrInt, SanCovLowestStack);
LowestStack->setNoSanitizeMetadata();
Store->setNoSanitizeMetadata();
|
As fixed in commits llvm/llvm-project@913f7e9, llvm/llvm-project@4a8b124, and llvm/llvm-project@4eef2e3, also fix the stack-depth tracking code to use InstrumentationIRBuilder, set the Store and Call's Debug location to EntryLoc, and update the tests to include stack-depth tests. ClangBuiltLinux/linux#2125
CI appears to be broken? "cp" failed? O_o |
Actual error seems to be:
which then causes the |
As fixed in commits 913f7e9, 4a8b124, and 4eef2e3, also fix the stack-depth tracking code to use InstrumentationIRBuilder, and set the Call's Debug location to EntryLoc.
ClangBuiltLinux/linux#2125
cc @nathanchance @melver @JustinStitt @bwendling