-
Notifications
You must be signed in to change notification settings - Fork 14.5k
Prevent a crash when a global variable has debug metadata #145918
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
Prevent a crash when a global variable has debug metadata #145918
Conversation
@llvm/pr-subscribers-debuginfo @llvm/pr-subscribers-llvm-ir Author: None (gbMattN) ChangesThis patch fixes a crash I found when trying to compile some codebases with -fsanitize=type and -g Full diff: https://github.com/llvm/llvm-project/pull/145918.diff 2 Files Affected:
diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp
index 5c645ffe3f3f7..c0ca896247ff3 100644
--- a/llvm/lib/IR/DebugInfo.cpp
+++ b/llvm/lib/IR/DebugInfo.cpp
@@ -50,7 +50,7 @@ TinyPtrVector<DbgDeclareInst *> llvm::findDbgDeclares(Value *V) {
// DenseMap lookup. This check is a bitfield datamember lookup.
if (!V->isUsedByMetadata())
return {};
- auto *L = LocalAsMetadata::getIfExists(V);
+ auto *L = ValueAsMetadata::getIfExists(V);
if (!L)
return {};
auto *MDV = MetadataAsValue::getIfExists(V->getContext(), L);
@@ -69,7 +69,7 @@ TinyPtrVector<DbgVariableRecord *> llvm::findDVRDeclares(Value *V) {
// DenseMap lookup. This check is a bitfield datamember lookup.
if (!V->isUsedByMetadata())
return {};
- auto *L = LocalAsMetadata::getIfExists(V);
+ auto *L = ValueAsMetadata::getIfExists(V);
if (!L)
return {};
diff --git a/llvm/unittests/IR/DebugInfoTest.cpp b/llvm/unittests/IR/DebugInfoTest.cpp
index 35bdbf8cc8321..1f88f249789f8 100644
--- a/llvm/unittests/IR/DebugInfoTest.cpp
+++ b/llvm/unittests/IR/DebugInfoTest.cpp
@@ -195,6 +195,44 @@ TEST(MetadataTest, DeleteInstUsedByDbgRecord) {
EXPECT_TRUE(isa<UndefValue>(DVRs[0]->getValue(0)));
}
+TEST(MetadataTest, GlobalConstantMetadataUsedByDbgRecord) {
+ LLVMContext C;
+ std::unique_ptr<Module> M = parseIR(C, R"(
+ @x = dso_local global i32 0, align 4
+ define i16 @f(i16 %a) !dbg !6 {
+ %b = add i16 %a, 1, !dbg !11
+ call void @llvm.dbg.declare(metadata ptr @x, metadata !9, metadata !DIExpression()), !dbg !11
+ ret i16 0, !dbg !11
+ }
+ declare void @llvm.dbg.value(metadata, metadata, metadata) #0
+ attributes #0 = { nounwind readnone speculatable willreturn }
+
+ !llvm.dbg.cu = !{!0}
+ !llvm.module.flags = !{!5}
+
+ !0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+ !1 = !DIFile(filename: "t.ll", directory: "/")
+ !2 = !{}
+ !5 = !{i32 2, !"Debug Info Version", i32 3}
+ !6 = distinct !DISubprogram(name: "foo", linkageName: "foo", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
+ !7 = !DISubroutineType(types: !2)
+ !8 = !{!9}
+ !9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)
+ !10 = !DIBasicType(name: "ty16", size: 16, encoding: DW_ATE_unsigned)
+ !11 = !DILocation(line: 1, column: 1, scope: !6)
+)");
+
+ // Find the global @x
+ Value* V = M->getNamedValue("x");
+
+ // Find the dbg.value
+ auto DVIs = findDbgDeclares(V);
+ auto DVRs = findDVRDeclares(V);
+
+ EXPECT_EQ(DVRs[0]->getNumVariableLocationOps(), 1u);
+ EXPECT_FALSE(isa<UndefValue>(DVRs[0]->getValue(0)));
+}
+
TEST(DbgVariableIntrinsic, EmptyMDIsKillLocation) {
LLVMContext Ctx;
std::unique_ptr<Module> M = parseIR(Ctx, R"(
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yikes, that's a pain -- so 'C' s being looked up from somewhere else and is wrong/bad? Any idea where the 'C' variable is coming from here? (Possibly we should do something else to ensure this isn't an error latent in other unit tests).
Hmmmph, got my wires crossed on reviews and patches there, lemmie try again... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Urgh. Discussed slightly offline, the fix is correct but it indicates that we've never been able to lookup debug-users of global variables in LLVM, ever, because of the VAM/LocalAsMetadata differences you're fixing here. Which is horrible, but I imagine it's not a common access pattern -- usually we look up the debug-users of a local instruction that's being fiddled with.
Would you be able to repeat the fix/unit-test for findDVRValues please, as it looks like that's vulnerable to the same issue.
Done so! |
4e75e08
to
ecbf511
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM; ship it!
This patch fixes a crash I found when trying to compile some codebases with -fsanitize=type and -g
This patch fixes a crash I found when trying to compile some codebases with -fsanitize=type and -g