forked from OSchip/llvm-project
[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:
parent
5579eb0a7a
commit
15eb237fd3
|
@ -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;
|
||||||
|
|
|
@ -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 !=
|
||||||
return nullptr;
|
Symbol->findChildrenEx(EnumVal, nullptr, nsNone, &DiaEnumerator)) {
|
||||||
|
if (S_OK != Symbol->findChildren(EnumVal, nullptr, nsNone, &DiaEnumerator))
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
return llvm::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
|
return llvm::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,80 +135,84 @@ 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)";
|
||||||
Printer.Indent();
|
Printer.Indent();
|
||||||
while (auto Enum = Enums->getNext())
|
while (auto Enum = Enums->getNext())
|
||||||
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)";
|
||||||
Printer.Indent();
|
Printer.Indent();
|
||||||
while (auto Typedef = Typedefs->getNext())
|
while (auto Typedef = Typedefs->getNext())
|
||||||
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();
|
||||||
WithColor(Printer, PDB_ColorItem::Identifier).get() << "Classes";
|
WithColor(Printer, PDB_ColorItem::Identifier).get() << "Classes";
|
||||||
|
|
||||||
bool Precompute = false;
|
bool Precompute = false;
|
||||||
Precompute =
|
Precompute =
|
||||||
(opts::pretty::ClassOrder != opts::pretty::ClassSortMode::None);
|
(opts::pretty::ClassOrder != opts::pretty::ClassSortMode::None);
|
||||||
|
|
||||||
// If we're using no sort mode, then we can start getting immediate output
|
// 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
|
// 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
|
// 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
|
// responsive. So only precompute the filtered/sorted set of classes if
|
||||||
// necessary due to the specified options.
|
// necessary due to the specified options.
|
||||||
std::vector<LayoutPtr> Filtered;
|
std::vector<LayoutPtr> Filtered;
|
||||||
uint32_t Shown = All;
|
uint32_t Shown = All;
|
||||||
if (Precompute) {
|
if (Precompute) {
|
||||||
Filtered = filterAndSortClassDefs(Printer, *Classes, All);
|
Filtered = filterAndSortClassDefs(Printer, *Classes, All);
|
||||||
|
|
||||||
Shown = Filtered.size();
|
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.Unindent();
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue