]> granicus.if.org Git - llvm/commitdiff
[PDB] Don't crash on /debug:fastlink PDBs.
authorZachary Turner <zturner@google.com>
Thu, 8 Jun 2017 16:00:40 +0000 (16:00 +0000)
committerZachary Turner <zturner@google.com>
Thu, 8 Jun 2017 16:00:40 +0000 (16:00 +0000)
Apparently support for /debug:fastlink PDBs isn't part of the
DIA SDK (!), and it was causing llvm-pdbdump to crash because
we weren't checking for a null pointer return value.  This
manifests when calling findChildren on the IDiaSymbol, and
it returns E_NOTIMPL.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304982 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/DebugInfo/PDB/PDBSymbol.h
lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
tools/llvm-pdbdump/PrettyTypeDumper.cpp

index b114b7afb0b03d86ff4365ebbd5caef28e793973..9e883d2f99a7abc4d008101093ca3b4ed0d10335 100644 (file)
@@ -89,6 +89,8 @@ public:
 
   template <typename T> std::unique_ptr<T> findOneChild() const {
     auto Enumerator(findAllChildren<T>());
+    if (!Enumerator)
+      return nullptr;
     return Enumerator->getNext();
   }
 
@@ -97,6 +99,8 @@ public:
   template <typename T>
   std::unique_ptr<ConcreteSymbolEnumerator<T>> findAllChildren() const {
     auto BaseIter = RawSymbol->findChildren(T::Tag);
+    if (!BaseIter)
+      return nullptr;
     return llvm::make_unique<ConcreteSymbolEnumerator<T>>(std::move(BaseIter));
   }
   std::unique_ptr<IPDBEnumSymbols> findAllChildren(PDB_SymType Type) const;
index 4e2474c51cb137a2db49c2c3880aac80df24d63b..0b48a366bd243300bf5e244596f74d43009ec3ca 100644 (file)
@@ -372,8 +372,11 @@ DIARawSymbol::findChildren(PDB_SymType Type) const {
   enum SymTagEnum EnumVal = static_cast<enum SymTagEnum>(Type);
 
   CComPtr<IDiaEnumSymbols> DiaEnumerator;
-  if (S_OK != Symbol->findChildrenEx(EnumVal, nullptr, nsNone, &DiaEnumerator))
-    return nullptr;
+  if (S_OK !=
+      Symbol->findChildrenEx(EnumVal, nullptr, nsNone, &DiaEnumerator)) {
+    if (S_OK != Symbol->findChildren(EnumVal, nullptr, nsNone, &DiaEnumerator))
+      return nullptr;
+  }
 
   return llvm::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
 }
index cd156f051573f3c200cfb727d2ea1f03a2b3d143..bbbb429f4f3f50d35221f1df19c90f5338039235 100644 (file)
@@ -135,80 +135,84 @@ filterAndSortClassDefs(LinePrinter &Printer, Enumerator &E,
 TypeDumper::TypeDumper(LinePrinter &P) : PDBSymDumper(true), Printer(P) {}
 
 void TypeDumper::start(const PDBSymbolExe &Exe) {
+  auto Children = Exe.findAllChildren();
   if (opts::pretty::Enums) {
-    auto Enums = Exe.findAllChildren<PDBSymbolTypeEnum>();
-    Printer.NewLine();
-    WithColor(Printer, PDB_ColorItem::Identifier).get() << "Enums";
-    Printer << ": (" << Enums->getChildCount() << " items)";
-    Printer.Indent();
-    while (auto Enum = Enums->getNext())
-      Enum->dump(*this);
-    Printer.Unindent();
+    if (auto Enums = Exe.findAllChildren<PDBSymbolTypeEnum>()) {
+      Printer.NewLine();
+      WithColor(Printer, PDB_ColorItem::Identifier).get() << "Enums";
+      Printer << ": (" << Enums->getChildCount() << " items)";
+      Printer.Indent();
+      while (auto Enum = Enums->getNext())
+        Enum->dump(*this);
+      Printer.Unindent();
+    }
   }
 
   if (opts::pretty::Typedefs) {
-    auto Typedefs = Exe.findAllChildren<PDBSymbolTypeTypedef>();
-    Printer.NewLine();
-    WithColor(Printer, PDB_ColorItem::Identifier).get() << "Typedefs";
-    Printer << ": (" << Typedefs->getChildCount() << " items)";
-    Printer.Indent();
-    while (auto Typedef = Typedefs->getNext())
-      Typedef->dump(*this);
-    Printer.Unindent();
+    if (auto Typedefs = Exe.findAllChildren<PDBSymbolTypeTypedef>()) {
+      Printer.NewLine();
+      WithColor(Printer, PDB_ColorItem::Identifier).get() << "Typedefs";
+      Printer << ": (" << Typedefs->getChildCount() << " items)";
+      Printer.Indent();
+      while (auto Typedef = Typedefs->getNext())
+        Typedef->dump(*this);
+      Printer.Unindent();
+    }
   }
 
   if (opts::pretty::Classes) {
-    auto Classes = Exe.findAllChildren<PDBSymbolTypeUDT>();
-    uint32_t All = Classes->getChildCount();
-
-    Printer.NewLine();
-    WithColor(Printer, PDB_ColorItem::Identifier).get() << "Classes";
-
-    bool Precompute = false;
-    Precompute =
-        (opts::pretty::ClassOrder != opts::pretty::ClassSortMode::None);
-
-    // If we're using no sort mode, then we can start getting immediate output
-    // from the tool by just filtering as we go, rather than processing
-    // everything up front so that we can sort it.  This makes the tool more
-    // responsive.  So only precompute the filtered/sorted set of classes if
-    // necessary due to the specified options.
-    std::vector<LayoutPtr> Filtered;
-    uint32_t Shown = All;
-    if (Precompute) {
-      Filtered = filterAndSortClassDefs(Printer, *Classes, All);
-
-      Shown = Filtered.size();
-    }
+    if (auto Classes = Exe.findAllChildren<PDBSymbolTypeUDT>()) {
+      uint32_t All = Classes->getChildCount();
+
+      Printer.NewLine();
+      WithColor(Printer, PDB_ColorItem::Identifier).get() << "Classes";
+
+      bool Precompute = false;
+      Precompute =
+          (opts::pretty::ClassOrder != opts::pretty::ClassSortMode::None);
+
+      // If we're using no sort mode, then we can start getting immediate output
+      // from the tool by just filtering as we go, rather than processing
+      // everything up front so that we can sort it.  This makes the tool more
+      // responsive.  So only precompute the filtered/sorted set of classes if
+      // necessary due to the specified options.
+      std::vector<LayoutPtr> Filtered;
+      uint32_t Shown = All;
+      if (Precompute) {
+        Filtered = filterAndSortClassDefs(Printer, *Classes, All);
+
+        Shown = Filtered.size();
+      }
 
-    Printer << ": (Showing " << Shown << " items";
-    if (Shown < All)
-      Printer << ", " << (All - Shown) << " filtered";
-    Printer << ")";
-    Printer.Indent();
-
-    // If we pre-computed, iterate the filtered/sorted list, otherwise iterate
-    // the DIA enumerator and filter on the fly.
-    if (Precompute) {
-      for (auto &Class : Filtered)
-        dumpClassLayout(*Class);
-    } else {
-      while (auto Class = Classes->getNext()) {
-        if (Class->getUnmodifiedTypeId() != 0)
-          continue;
-
-        if (Printer.IsTypeExcluded(Class->getName(), Class->getLength()))
-          continue;
-
-        auto Layout = llvm::make_unique<ClassLayout>(std::move(Class));
-        if (Layout->deepPaddingSize() < opts::pretty::PaddingThreshold)
-          continue;
-
-        dumpClassLayout(*Layout);
+      Printer << ": (Showing " << Shown << " items";
+      if (Shown < All)
+        Printer << ", " << (All - Shown) << " filtered";
+      Printer << ")";
+      Printer.Indent();
+
+      // If we pre-computed, iterate the filtered/sorted list, otherwise iterate
+      // the DIA enumerator and filter on the fly.
+      if (Precompute) {
+        for (auto &Class : Filtered)
+          dumpClassLayout(*Class);
+      } else {
+        while (auto Class = Classes->getNext()) {
+          if (Class->getUnmodifiedTypeId() != 0)
+            continue;
+
+          if (Printer.IsTypeExcluded(Class->getName(), Class->getLength()))
+            continue;
+
+          auto Layout = llvm::make_unique<ClassLayout>(std::move(Class));
+          if (Layout->deepPaddingSize() < opts::pretty::PaddingThreshold)
+            continue;
+
+          dumpClassLayout(*Layout);
+        }
       }
-    }
 
-    Printer.Unindent();
+      Printer.Unindent();
+    }
   }
 }