[Debuginfo][NFC] Create common error handlers for DWARFContext.
authorAlexey Lapshin <a.v.lapshin@mail.ru>
Tue, 11 Feb 2020 15:32:27 +0000 (18:32 +0300)
committerAlexey Lapshin <a.v.lapshin@mail.ru>
Sat, 15 Feb 2020 09:46:17 +0000 (12:46 +0300)
Summary:
this review is extracted from D74308.

It creates two error handlers which allow to redefine error
reporting routine and should be used for all places
where errors are reported:

  std::function<void(Error)> RecoverableErrorHandler = defaultErrorHandler;
  std::function<void(Error)> WarningHandler = defaultWarningHandler;

It also creates accessors to above handlers which should be used to
report errors.

  function_ref<void(Error)> getRecoverableErrorHandler() {
    return RecoverableErrorHandler;
  }

  function_ref<void(Error)> getWarningHandler() { return WarningHandler; }

It patches all error reporting places inside DWARFContext and DWARLinker.

Reviewers: jhenderson, dblaikie, probinson, aprantl, JDevlieghere

Reviewed By: jhenderson, JDevlieghere

Subscribers: hiraditya, llvm-commits

Tags: #llvm, #debug-info

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

llvm/include/llvm/DebugInfo/DIContext.h
llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
llvm/include/llvm/Support/WithColor.h
llvm/lib/DWARFLinker/DWARFLinker.cpp
llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
llvm/lib/Support/WithColor.cpp

index b32bb17..0bad415 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/WithColor.h"
 #include "llvm/Support/raw_ostream.h"
 #include <cassert>
 #include <cstdint>
@@ -204,6 +205,10 @@ struct DIDumpOptions {
       Opts.ParentRecurseDepth = 0;
     return Opts;
   }
+
+  std::function<void(Error)> RecoverableErrorHandler =
+      WithColor::defaultErrorHandler;
+  std::function<void(Error)> WarningHandler = WithColor::defaultWarningHandler;
 };
 
 class DIContext {
index 8c17282..1b3fffe 100644 (file)
@@ -91,6 +91,9 @@ class DWARFContext : public DIContext {
 
   std::unique_ptr<MCRegisterInfo> RegInfo;
 
+  std::function<void(Error)> RecoverableErrorHandler = defaultErrorHandler;
+  std::function<void(Error)> WarningHandler = WithColor::defaultWarningHandler;
+
   /// Read compile units from the debug_info section (if necessary)
   /// and type units from the debug_types sections (if necessary)
   /// and store them in NormalUnits.
@@ -343,9 +346,16 @@ public:
 
   const MCRegisterInfo *getRegisterInfo() const { return RegInfo.get(); }
 
+  function_ref<void(Error)> getRecoverableErrorHandler() {
+    return RecoverableErrorHandler;
+  }
+
+  function_ref<void(Error)> getWarningHandler() { return WarningHandler; }
+
   /// Function used to handle default error reporting policy. Prints a error
   /// message and returns Continue, so DWARF context ignores the error.
   static ErrorPolicy defaultErrorHandler(Error E);
+
   static std::unique_ptr<DWARFContext>
   create(const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr,
          function_ref<ErrorPolicy(Error)> HandleError = defaultErrorHandler,
@@ -364,9 +374,6 @@ public:
   /// TODO: refactor compile_units() to make this const.
   uint8_t getCUAddrSize();
 
-  /// Dump Error as warning message to stderr.
-  static void dumpWarning(Error Warning);
-
   Triple::ArchType getArch() const {
     return getDWARFObj().getFile()->getArch();
   }
index f4e1075..96b2b71 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Error.h"
 
 namespace llvm {
 
@@ -108,6 +109,9 @@ public:
   /// Reset the colors to terminal defaults. Call this when you are done
   /// outputting colored text, or before program exit.
   WithColor &resetColor();
+
+  static void defaultErrorHandler(Error Err);
+  static void defaultWarningHandler(Error Warning);
 };
 
 } // end namespace llvm
index 715ad24..84a4037 100644 (file)
@@ -1548,9 +1548,10 @@ void DWARFLinker::patchLineTableForUnit(CompileUnit &Unit,
   if (needToTranslateStrings())
     return TheDwarfEmitter->translateLineTable(LineExtractor, StmtOffset);
 
-  Error Err = LineTable.parse(LineExtractor, &StmtOffset, OrigDwarf,
-                              &Unit.getOrigUnit(), DWARFContext::dumpWarning);
-  DWARFContext::dumpWarning(std::move(Err));
+  if (Error Err =
+          LineTable.parse(LineExtractor, &StmtOffset, OrigDwarf,
+                          &Unit.getOrigUnit(), OrigDwarf.getWarningHandler()))
+    OrigDwarf.getWarningHandler()(std::move(Err));
 
   // This vector is the output line table.
   std::vector<DWARFDebugLine::Row> NewRows;
index 62bc513..7b0be01 100644 (file)
@@ -45,7 +45,6 @@
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/TargetRegistry.h"
-#include "llvm/Support/WithColor.h"
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
 #include <cstdint>
@@ -131,9 +130,10 @@ collectContributionData(DWARFContext::unit_iterator_range Units) {
 }
 
 static void dumpDWARFv5StringOffsetsSection(
-    raw_ostream &OS, StringRef SectionName, const DWARFObject &Obj,
-    const DWARFSection &StringOffsetsSection, StringRef StringSection,
-    DWARFContext::unit_iterator_range Units, bool LittleEndian) {
+    raw_ostream &OS, DIDumpOptions DumpOpts, StringRef SectionName,
+    const DWARFObject &Obj, const DWARFSection &StringOffsetsSection,
+    StringRef StringSection, DWARFContext::unit_iterator_range Units,
+    bool LittleEndian) {
   auto Contributions = collectContributionData(Units);
   DWARFDataExtractor StrOffsetExt(Obj, StringOffsetsSection, LittleEndian, 0);
   DataExtractor StrData(StringSection, LittleEndian, 0);
@@ -159,10 +159,10 @@ static void dumpDWARFv5StringOffsetsSection(
 
     // Detect overlapping contributions.
     if (Offset > ContributionHeader) {
-      WithColor::error()
-          << "overlapping contributions to string offsets table in section ."
-          << SectionName << ".\n";
-      return;
+      DumpOpts.RecoverableErrorHandler(createStringError(
+          errc::invalid_argument,
+          "overlapping contributions to string offsets table in section .%s.",
+          SectionName.data()));
     }
     // Report a gap in the table.
     if (Offset < ContributionHeader) {
@@ -204,7 +204,8 @@ static void dumpDWARFv5StringOffsetsSection(
 // a header containing size and version number. Alternatively, it may be a
 // monolithic series of string offsets, as generated by the pre-DWARF v5
 // implementation of split DWARF.
-static void dumpStringOffsetsSection(raw_ostream &OS, StringRef SectionName,
+static void dumpStringOffsetsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
+                                     StringRef SectionName,
                                      const DWARFObject &Obj,
                                      const DWARFSection &StringOffsetsSection,
                                      StringRef StringSection,
@@ -214,8 +215,9 @@ static void dumpStringOffsetsSection(raw_ostream &OS, StringRef SectionName,
   // we assume that the section is formatted like a DWARF v5 string offsets
   // section.
   if (MaxVersion >= 5)
-    dumpDWARFv5StringOffsetsSection(OS, SectionName, Obj, StringOffsetsSection,
-                                    StringSection, Units, LittleEndian);
+    dumpDWARFv5StringOffsetsSection(OS, DumpOpts, SectionName, Obj,
+                                    StringOffsetsSection, StringSection, Units,
+                                    LittleEndian);
   else {
     DataExtractor strOffsetExt(StringOffsetsSection.Data, LittleEndian, 0);
     uint64_t offset = 0;
@@ -248,8 +250,8 @@ static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData,
     DWARFDebugAddrTable AddrTable;
     uint64_t TableOffset = Offset;
     if (Error Err = AddrTable.extract(AddrData, &Offset, Version, AddrSize,
-                                      DWARFContext::dumpWarning)) {
-      WithColor::error() << toString(std::move(Err)) << '\n';
+                                      DumpOpts.WarningHandler)) {
+      DumpOpts.RecoverableErrorHandler(std::move(Err));
       // Keep going after an error, if we can, assuming that the length field
       // could be read. If it couldn't, stop reading the section.
       if (auto TableLength = AddrTable.getFullLength()) {
@@ -273,7 +275,7 @@ static void dumpRnglistsSection(
     llvm::DWARFDebugRnglistTable Rnglists;
     uint64_t TableOffset = Offset;
     if (Error Err = Rnglists.extract(rnglistData, &Offset)) {
-      WithColor::error() << toString(std::move(Err)) << '\n';
+      DumpOpts.RecoverableErrorHandler(std::move(Err));
       uint64_t Length = Rnglists.length();
       // Keep going after an error, if we can, assuming that the length field
       // could be read. If it couldn't, stop reading the section.
@@ -296,7 +298,7 @@ static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
   while (Data.isValidOffset(Offset)) {
     DWARFListTableHeader Header(".debug_loclists", "locations");
     if (Error E = Header.extract(Data, &Offset)) {
-      WithColor::error() << toString(std::move(E)) << '\n';
+      DumpOpts.RecoverableErrorHandler(std::move(E));
       return;
     }
 
@@ -323,7 +325,6 @@ static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
 void DWARFContext::dump(
     raw_ostream &OS, DIDumpOptions DumpOpts,
     std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets) {
-
   uint64_t DumpType = DumpOpts.DumpType;
 
   StringRef Extension = sys::path::extension(DObj->getFileName());
@@ -456,7 +457,7 @@ void DWARFContext::dump(
     DWARFDebugArangeSet set;
     while (arangesData.isValidOffset(offset)) {
       if (Error E = set.extract(arangesData, &offset)) {
-        WithColor::error() << toString(std::move(E)) << '\n';
+        RecoverableErrorHandler(std::move(E));
         break;
       }
       set.dump(OS);
@@ -468,16 +469,16 @@ void DWARFContext::dump(
                              Optional<uint64_t> DumpOffset) {
     while (!Parser.done()) {
       if (DumpOffset && Parser.getOffset() != *DumpOffset) {
-        Parser.skip(dumpWarning, dumpWarning);
+        Parser.skip(DumpOpts.WarningHandler, DumpOpts.WarningHandler);
         continue;
       }
       OS << "debug_line[" << format("0x%8.8" PRIx64, Parser.getOffset())
          << "]\n";
       if (DumpOpts.Verbose) {
-        Parser.parseNext(dumpWarning, dumpWarning, &OS);
+        Parser.parseNext(DumpOpts.WarningHandler, DumpOpts.WarningHandler, &OS);
       } else {
         DWARFDebugLine::LineTable LineTable =
-            Parser.parseNext(dumpWarning, dumpWarning);
+            Parser.parseNext(DumpOpts.WarningHandler, DumpOpts.WarningHandler);
         LineTable.dump(OS, DumpOpts);
       }
     }
@@ -561,7 +562,7 @@ void DWARFContext::dump(
     DWARFDebugRangeList rangeList;
     while (rangesData.isValidOffset(offset)) {
       if (Error E = rangeList.extract(rangesData, &offset)) {
-        WithColor::error() << toString(std::move(E)) << '\n';
+        DumpOpts.RecoverableErrorHandler(std::move(E));
         break;
       }
       rangeList.dump(OS);
@@ -614,13 +615,13 @@ void DWARFContext::dump(
 
   if (shouldDump(Explicit, ".debug_str_offsets", DIDT_ID_DebugStrOffsets,
                  DObj->getStrOffsetsSection().Data))
-    dumpStringOffsetsSection(OS, "debug_str_offsets", *DObj,
+    dumpStringOffsetsSection(OS, DumpOpts, "debug_str_offsets", *DObj,
                              DObj->getStrOffsetsSection(),
                              DObj->getStrSection(), normal_units(),
                              isLittleEndian(), getMaxVersion());
   if (shouldDump(ExplicitDWO, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets,
                  DObj->getStrOffsetsDWOSection().Data))
-    dumpStringOffsetsSection(OS, "debug_str_offsets.dwo", *DObj,
+    dumpStringOffsetsSection(OS, DumpOpts, "debug_str_offsets.dwo", *DObj,
                              DObj->getStrOffsetsDWOSection(),
                              DObj->getStrDWOSection(), dwo_units(),
                              isLittleEndian(), getMaxDWOVersion());
@@ -871,9 +872,9 @@ const AppleAcceleratorTable &DWARFContext::getAppleObjC() {
 const DWARFDebugLine::LineTable *
 DWARFContext::getLineTableForUnit(DWARFUnit *U) {
   Expected<const DWARFDebugLine::LineTable *> ExpectedLineTable =
-      getLineTableForUnit(U, dumpWarning);
+      getLineTableForUnit(U, WarningHandler);
   if (!ExpectedLineTable) {
-    dumpWarning(ExpectedLineTable.takeError());
+    WarningHandler(ExpectedLineTable.takeError());
     return nullptr;
   }
   return *ExpectedLineTable;
@@ -1425,7 +1426,7 @@ static bool isRelocScattered(const object::ObjectFile &Obj,
 }
 
 ErrorPolicy DWARFContext::defaultErrorHandler(Error E) {
-  WithColor::error() << toString(std::move(E)) << '\n';
+  WithColor::defaultErrorHandler(std::move(E));
   return ErrorPolicy::Continue;
 }
 
@@ -1941,8 +1942,3 @@ uint8_t DWARFContext::getCUAddrSize() {
   return Addr;
 }
 
-void DWARFContext::dumpWarning(Error Warning) {
-  handleAllErrors(std::move(Warning), [](ErrorInfoBase &Info) {
-      WithColor::warning() << Info.message() << '\n';
-  });
-}
index 345dd9c..250500e 100644 (file)
@@ -118,3 +118,15 @@ WithColor &WithColor::resetColor() {
 }
 
 WithColor::~WithColor() { resetColor(); }
+
+void WithColor::defaultErrorHandler(Error Err) {
+  handleAllErrors(std::move(Err), [](ErrorInfoBase &Info) {
+    WithColor::error() << Info.message() << '\n';
+  });
+}
+
+void WithColor::defaultWarningHandler(Error Warning) {
+  handleAllErrors(std::move(Warning), [](ErrorInfoBase &Info) {
+    WithColor::warning() << Info.message() << '\n';
+  });
+}