[llvm] r268936 - Allow the LTO code generator to strip invalid debug info from the input.

Adrian Prantl via llvm-commits llvm-commits at lists.llvm.org
Mon May 9 10:37:34 PDT 2016


Author: adrian
Date: Mon May  9 12:37:33 2016
New Revision: 268936

URL: http://llvm.org/viewvc/llvm-project?rev=268936&view=rev
Log:
Allow the LTO code generator to strip invalid debug info from the input.

This patch introduces a new option -lto-strip-invalid-debug-info, which
drops malformed debug info from the input.

The problem I'm trying to solve with this sequence of patches is that
historically we've done a really bad job at verifying debug info. We want
to be able to make the verifier stricter without having to worry about
breaking bitcode compatibility with existing producers. For example, we
don't necessarily want IR produced by an older version of clang to be
rejected by an LTO link just because of malformed debug info, and rather
provide an option to strip it. Note that merely outdated (but well-formed)
debug info would continue to be auto-upgraded in this scenario.

rdar://problem/25818489
http://reviews.llvm.org/D19987

Added:
    llvm/trunk/test/LTO/X86/Inputs/strip-debug-info.bc
    llvm/trunk/test/LTO/X86/strip-debug-info.ll
Modified:
    llvm/trunk/include/llvm/IR/Verifier.h
    llvm/trunk/lib/IR/Verifier.cpp
    llvm/trunk/lib/LTO/LTOCodeGenerator.cpp

Modified: llvm/trunk/include/llvm/IR/Verifier.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Verifier.h?rev=268936&r1=268935&r2=268936&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Verifier.h (original)
+++ llvm/trunk/include/llvm/IR/Verifier.h Mon May  9 12:37:33 2016
@@ -41,10 +41,16 @@ bool verifyFunction(const Function &F, r
 
 /// \brief Check a module for errors.
 ///
-/// If there are no errors, the function returns false. If an error is found,
-/// a message describing the error is written to OS (if non-null) and true is
-/// returned.
-bool verifyModule(const Module &M, raw_ostream *OS = nullptr);
+/// If there are no errors, the function returns false. If an error is
+/// found, a message describing the error is written to OS (if
+/// non-null) and true is returned.
+///
+/// \return true if the module is broken. If BrokenDebugInfo is
+/// supplied, DebugInfo verification failures won't be considered as
+/// error and instead *BrokenDebugInfo will be set to true. Debug
+/// info errors can be "recovered" from by stripping the debug info.
+bool verifyModule(const Module &M, raw_ostream *OS = nullptr,
+                  bool *BrokenDebugInfo = nullptr);
 
 /// \brief Create a verifier pass.
 ///

Modified: llvm/trunk/lib/IR/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Verifier.cpp?rev=268936&r1=268935&r2=268936&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Verifier.cpp (original)
+++ llvm/trunk/lib/IR/Verifier.cpp Mon May  9 12:37:33 2016
@@ -4417,18 +4417,22 @@ bool llvm::verifyFunction(const Function
   return !V.verify(F);
 }
 
-bool llvm::verifyModule(const Module &M, raw_ostream *OS) {
+bool llvm::verifyModule(const Module &M, raw_ostream *OS,
+                        bool *BrokenDebugInfo) {
   // Don't use a raw_null_ostream.  Printing IR is expensive.
-  Verifier V(OS, /*ShouldTreatBrokenDebugInfoAsError=*/true);
+  Verifier V(OS, /*ShouldTreatBrokenDebugInfoAsError=*/!BrokenDebugInfo);
 
   bool Broken = false;
   for (const Function &F : M)
     if (!F.isDeclaration() && !F.isMaterializable())
       Broken |= !V.verify(F);
 
+  Broken |= !V.verify(M);
+  if (BrokenDebugInfo)
+    *BrokenDebugInfo = V.hasBrokenDebugInfo();
   // Note that this function's return value is inverted from what you would
   // expect of a function called "verify".
-  return !V.verify(M) || Broken;
+  return Broken;
 }
 
 namespace {

Modified: llvm/trunk/lib/LTO/LTOCodeGenerator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/LTOCodeGenerator.cpp?rev=268936&r1=268935&r2=268936&view=diff
==============================================================================
--- llvm/trunk/lib/LTO/LTOCodeGenerator.cpp (original)
+++ llvm/trunk/lib/LTO/LTOCodeGenerator.cpp Mon May  9 12:37:33 2016
@@ -26,6 +26,7 @@
 #include "llvm/Config/config.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DataLayout.h"
+#include "llvm/IR/DebugInfo.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/DiagnosticPrinter.h"
@@ -78,6 +79,16 @@ cl::opt<bool> LTODiscardValueNames(
     cl::init(false),
 #endif
     cl::Hidden);
+
+cl::opt<bool> LTOStripInvalidDebugInfo(
+    "lto-strip-invalid-debug-info",
+    cl::desc("Strip invalid debug info metadata during LTO instead of aborting."),
+#ifdef NDEBUG
+    cl::init(true),
+#else
+    cl::init(false),
+#endif
+    cl::Hidden);
 }
 
 LTOCodeGenerator::LTOCodeGenerator(LLVMContext &Context)
@@ -488,6 +499,15 @@ void LTOCodeGenerator::verifyMergedModul
     return;
   HasVerifiedInput = true;
 
+  if (LTOStripInvalidDebugInfo) {
+    bool BrokenDebugInfo = false;
+    if (verifyModule(*MergedModule, &dbgs(), &BrokenDebugInfo))
+      report_fatal_error("Broken module found, compilation aborted!");
+    if (BrokenDebugInfo) {
+      emitWarning("Invalid debug info found, debug info will be stripped");
+      StripDebugInfo(*MergedModule);
+    }
+  }
   if (verifyModule(*MergedModule, &dbgs()))
     report_fatal_error("Broken module found, compilation aborted!");
 }

Added: llvm/trunk/test/LTO/X86/Inputs/strip-debug-info.bc
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LTO/X86/Inputs/strip-debug-info.bc?rev=268936&view=auto
==============================================================================
Binary files llvm/trunk/test/LTO/X86/Inputs/strip-debug-info.bc (added) and llvm/trunk/test/LTO/X86/Inputs/strip-debug-info.bc Mon May  9 12:37:33 2016 differ

Added: llvm/trunk/test/LTO/X86/strip-debug-info.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/LTO/X86/strip-debug-info.ll?rev=268936&view=auto
==============================================================================
--- llvm/trunk/test/LTO/X86/strip-debug-info.ll (added)
+++ llvm/trunk/test/LTO/X86/strip-debug-info.ll Mon May  9 12:37:33 2016
@@ -0,0 +1,20 @@
+; RUN: not llvm-lto -lto-strip-invalid-debug-info=false \
+; RUN:     -o %t.o %S/Inputs/strip-debug-info.bc 2>&1 | \
+; RUN:     FileCheck %s -allow-empty -check-prefix=CHECK-ERR
+; RUN: llvm-lto -lto-strip-invalid-debug-info=true -exported-symbol _foo \
+; RUN:     -o %t.o %S/Inputs/strip-debug-info.bc 2>&1 | \
+; RUN:     FileCheck %s -allow-empty -check-prefix=CHECK-WARN
+; RUN: llvm-nm %t.o | FileCheck %s 
+
+; CHECK-ERR: Broken module found, compilation aborted
+; CHECK-WARN: Invalid debug info found, debug info will be stripped
+; CHECK: foo
+define void @foo() {
+  ret void
+}
+
+!llvm.module.flags = !{!0}
+!llvm.dbg.cu = !{!1}
+
+!0 = !{i32 2, !"Debug Info Version", i32 3}
+!1 = !DIFile(filename: "broken", directory: "")




More information about the llvm-commits mailing list