[PDB] Don't crash on /debug:fastlink PDBs.

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.

llvm-svn: 304982
This commit is contained in:
Zachary Turner 2017-06-08 16:00:40 +00:00
parent 5579eb0a7a
commit 15eb237fd3
3 changed files with 74 additions and 63 deletions

View File

@ -89,6 +89,8 @@ public:
template <typename T> std::unique_ptr<T> findOneChild() const { template <typename T> std::unique_ptr<T> findOneChild() const {
auto Enumerator(findAllChildren<T>()); auto Enumerator(findAllChildren<T>());
if (!Enumerator)
return nullptr;
return Enumerator->getNext(); return Enumerator->getNext();
} }
@ -97,6 +99,8 @@ public:
template <typename T> template <typename T>
std::unique_ptr<ConcreteSymbolEnumerator<T>> findAllChildren() const { std::unique_ptr<ConcreteSymbolEnumerator<T>> findAllChildren() const {
auto BaseIter = RawSymbol->findChildren(T::Tag); auto BaseIter = RawSymbol->findChildren(T::Tag);
if (!BaseIter)
return nullptr;
return llvm::make_unique<ConcreteSymbolEnumerator<T>>(std::move(BaseIter)); return llvm::make_unique<ConcreteSymbolEnumerator<T>>(std::move(BaseIter));
} }
std::unique_ptr<IPDBEnumSymbols> findAllChildren(PDB_SymType Type) const; std::unique_ptr<IPDBEnumSymbols> findAllChildren(PDB_SymType Type) const;

View File

@ -372,8 +372,11 @@ DIARawSymbol::findChildren(PDB_SymType Type) const {
enum SymTagEnum EnumVal = static_cast<enum SymTagEnum>(Type); enum SymTagEnum EnumVal = static_cast<enum SymTagEnum>(Type);
CComPtr<IDiaEnumSymbols> DiaEnumerator; CComPtr<IDiaEnumSymbols> DiaEnumerator;
if (S_OK != Symbol->findChildrenEx(EnumVal, nullptr, nsNone, &DiaEnumerator)) if (S_OK !=
Symbol->findChildrenEx(EnumVal, nullptr, nsNone, &DiaEnumerator)) {
if (S_OK != Symbol->findChildren(EnumVal, nullptr, nsNone, &DiaEnumerator))
return nullptr; return nullptr;
}
return llvm::make_unique<DIAEnumSymbols>(Session, DiaEnumerator); return llvm::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
} }

View File

@ -135,8 +135,9 @@ filterAndSortClassDefs(LinePrinter &Printer, Enumerator &E,
TypeDumper::TypeDumper(LinePrinter &P) : PDBSymDumper(true), Printer(P) {} TypeDumper::TypeDumper(LinePrinter &P) : PDBSymDumper(true), Printer(P) {}
void TypeDumper::start(const PDBSymbolExe &Exe) { void TypeDumper::start(const PDBSymbolExe &Exe) {
auto Children = Exe.findAllChildren();
if (opts::pretty::Enums) { if (opts::pretty::Enums) {
auto Enums = Exe.findAllChildren<PDBSymbolTypeEnum>(); if (auto Enums = Exe.findAllChildren<PDBSymbolTypeEnum>()) {
Printer.NewLine(); Printer.NewLine();
WithColor(Printer, PDB_ColorItem::Identifier).get() << "Enums"; WithColor(Printer, PDB_ColorItem::Identifier).get() << "Enums";
Printer << ": (" << Enums->getChildCount() << " items)"; Printer << ": (" << Enums->getChildCount() << " items)";
@ -145,9 +146,10 @@ void TypeDumper::start(const PDBSymbolExe &Exe) {
Enum->dump(*this); Enum->dump(*this);
Printer.Unindent(); Printer.Unindent();
} }
}
if (opts::pretty::Typedefs) { if (opts::pretty::Typedefs) {
auto Typedefs = Exe.findAllChildren<PDBSymbolTypeTypedef>(); if (auto Typedefs = Exe.findAllChildren<PDBSymbolTypeTypedef>()) {
Printer.NewLine(); Printer.NewLine();
WithColor(Printer, PDB_ColorItem::Identifier).get() << "Typedefs"; WithColor(Printer, PDB_ColorItem::Identifier).get() << "Typedefs";
Printer << ": (" << Typedefs->getChildCount() << " items)"; Printer << ": (" << Typedefs->getChildCount() << " items)";
@ -156,9 +158,10 @@ void TypeDumper::start(const PDBSymbolExe &Exe) {
Typedef->dump(*this); Typedef->dump(*this);
Printer.Unindent(); Printer.Unindent();
} }
}
if (opts::pretty::Classes) { if (opts::pretty::Classes) {
auto Classes = Exe.findAllChildren<PDBSymbolTypeUDT>(); if (auto Classes = Exe.findAllChildren<PDBSymbolTypeUDT>()) {
uint32_t All = Classes->getChildCount(); uint32_t All = Classes->getChildCount();
Printer.NewLine(); Printer.NewLine();
@ -210,6 +213,7 @@ void TypeDumper::start(const PDBSymbolExe &Exe) {
Printer.Unindent(); Printer.Unindent();
} }
}
} }
void TypeDumper::dump(const PDBSymbolTypeEnum &Symbol) { void TypeDumper::dump(const PDBSymbolTypeEnum &Symbol) {