[lld] ac2226b - [PDB] Improve error handling when writes fail

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Tue May 18 13:20:29 PDT 2021


Author: Reid Kleckner
Date: 2021-05-18T13:17:17-07:00
New Revision: ac2226b0f573226620e8aecdcc079f74612dfe48

URL: https://github.com/llvm/llvm-project/commit/ac2226b0f573226620e8aecdcc079f74612dfe48
DIFF: https://github.com/llvm/llvm-project/commit/ac2226b0f573226620e8aecdcc079f74612dfe48.diff

LOG: [PDB] Improve error handling when writes fail

Handle PDB writing errors like any other error in LLD: emit an error and
continue. This allows the linker to print timing data and summary data
after linking, which can be helpful for finding PDB size problems. Also
report how large the file would have been.

Example output:

lld-link: error: Output data is larger than 4 GiB. File size would have been 6,937,108,480
lld-link: error: failed to write PDB file ./chrome.dll.pdb
                                    Summary
--------------------------------------------------------------------------------
          33282 Input OBJ files (expanded from all cmd-line inputs)
              4 PDB type server dependencies
              0 Precomp OBJ dependencies
       33396931 Input type records
... snip ...
  Input File Reading:           59756 ms ( 45.5%)
  GC:                            7500 ms (  5.7%)
  ICF:                           3336 ms (  2.5%)
  Code Layout:                   6329 ms (  4.8%)
  PDB Emission (Cumulative):    46192 ms ( 35.2%)
    Add Objects:                27609 ms ( 21.0%)
      Type Merging:             16740 ms ( 12.8%)
      Symbol Merging:           10761 ms (  8.2%)
    Publics Stream Layout:       9383 ms (  7.1%)
    TPI Stream Layout:           1678 ms (  1.3%)
    Commit to Disk:              3461 ms (  2.6%)
--------------------------------------------------
Total Link Time:               131244 ms (100.0%)

Differential Revision: https://reviews.llvm.org/D102713

Added: 
    

Modified: 
    lld/COFF/PDB.cpp
    llvm/include/llvm/DebugInfo/MSF/MSFError.h
    llvm/lib/DebugInfo/MSF/MSFBuilder.cpp
    llvm/lib/DebugInfo/MSF/MSFError.cpp

Removed: 
    


################################################################################
diff  --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp
index dac8bb5d2d7f..6791d523da37 100644
--- a/lld/COFF/PDB.cpp
+++ b/lld/COFF/PDB.cpp
@@ -1648,9 +1648,13 @@ void PDBLinker::addSections(ArrayRef<OutputSection *> outputSections,
 }
 
 void PDBLinker::commit(codeview::GUID *guid) {
-  ExitOnError exitOnErr((config->pdbPath + ": ").str());
-  // Write to a file.
-  exitOnErr(builder.commit(config->pdbPath, guid));
+  // Print an error and continue if PDB writing fails. This is done mainly so
+  // the user can see the output of /time and /summary, which is very helpful
+  // when trying to figure out why a PDB file is too large.
+  if (Error e = builder.commit(config->pdbPath, guid)) {
+    checkError(std::move(e));
+    error("failed to write PDB file " + Twine(config->pdbPath));
+  }
 }
 
 static uint32_t getSecrelReloc() {

diff  --git a/llvm/include/llvm/DebugInfo/MSF/MSFError.h b/llvm/include/llvm/DebugInfo/MSF/MSFError.h
index fbc4e6928536..67962fbd5028 100644
--- a/llvm/include/llvm/DebugInfo/MSF/MSFError.h
+++ b/llvm/include/llvm/DebugInfo/MSF/MSFError.h
@@ -18,6 +18,7 @@ namespace msf {
 enum class msf_error_code {
   unspecified = 1,
   insufficient_buffer,
+  size_overflow,
   not_writable,
   no_stream,
   invalid_format,

diff  --git a/llvm/lib/DebugInfo/MSF/MSFBuilder.cpp b/llvm/lib/DebugInfo/MSF/MSFBuilder.cpp
index a02b9ea9e35b..1a92e2cb7754 100644
--- a/llvm/lib/DebugInfo/MSF/MSFBuilder.cpp
+++ b/llvm/lib/DebugInfo/MSF/MSFBuilder.cpp
@@ -15,6 +15,7 @@
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/FileOutputBuffer.h"
+#include "llvm/Support/FormatVariadic.h"
 #include <algorithm>
 #include <cassert>
 #include <cstdint>
@@ -348,8 +349,9 @@ Expected<FileBufferByteStream> MSFBuilder::commit(StringRef Path,
     // block-based and as long as each stream is small enough, PDBs larger than
     // 4 GiB might work. Check if tools can handle these large PDBs, and if so
     // add support for writing them.
-    return make_error<MSFError>(msf_error_code::invalid_format,
-                                "Output larger than 4 GiB");
+    return make_error<MSFError>(
+        msf_error_code::size_overflow,
+        formatv("File size would have been {0,1:N}", FileSize));
   }
 
   auto OutFileOrError = FileOutputBuffer::create(Path, FileSize);

diff  --git a/llvm/lib/DebugInfo/MSF/MSFError.cpp b/llvm/lib/DebugInfo/MSF/MSFError.cpp
index b368b802c564..f068d3334955 100644
--- a/llvm/lib/DebugInfo/MSF/MSFError.cpp
+++ b/llvm/lib/DebugInfo/MSF/MSFError.cpp
@@ -27,6 +27,8 @@ class MSFErrorCategory : public std::error_category {
     case msf_error_code::insufficient_buffer:
       return "The buffer is not large enough to read the requested number of "
              "bytes.";
+    case msf_error_code::size_overflow:
+      return "Output data is larger than 4 GiB.";
     case msf_error_code::not_writable:
       return "The specified stream is not writable.";
     case msf_error_code::no_stream:


        


More information about the llvm-commits mailing list