summaryrefslogtreecommitdiffstats
path: root/lld/COFF/PDB.cpp
diff options
context:
space:
mode:
authorAlexandre Ganea <alexandre.ganea@ubisoft.com>2018-09-10 13:51:21 +0000
committerAlexandre Ganea <alexandre.ganea@ubisoft.com>2018-09-10 13:51:21 +0000
commitd93b07f0b09c55bb7e01b463a822b214d141d6a8 (patch)
tree158c18b2a37a24b45b1628fab72886f039f6b99e /lld/COFF/PDB.cpp
parenta32d253f10cb7dccf17ffaeaa037c6bef453a6d5 (diff)
downloadbcm5719-llvm-d93b07f0b09c55bb7e01b463a822b214d141d6a8.tar.gz
bcm5719-llvm-d93b07f0b09c55bb7e01b463a822b214d141d6a8.zip
[LLD][COFF] Cleanup error messages / add more coverage tests
- Log the reason for a PDB or precompiled-OBJ load failure - Properly handle out-of-date PDB or precompiled-OBJ signature by displaying a corresponding error - Slightly change behavior on PDB failure: any subsequent load attempt from another OBJ would result in the same error message being logged - Slightly change behavior on PDB failure: retry with filename only if previous error was ENOENT ("no such file or directory") - Tests: a. for native PDB errors; b. cover all the cases above Differential Revision: https://reviews.llvm.org/D51559 llvm-svn: 341825
Diffstat (limited to 'lld/COFF/PDB.cpp')
-rw-r--r--lld/COFF/PDB.cpp62
1 files changed, 41 insertions, 21 deletions
diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp
index 08cde6f06eb..bb6d246fa11 100644
--- a/lld/COFF/PDB.cpp
+++ b/lld/COFF/PDB.cpp
@@ -165,7 +165,7 @@ private:
/// List of TypeServer PDBs which cannot be loaded.
/// Cached to prevent repeated load attempts.
- std::set<GUID> MissingTypeServerPDBs;
+ std::map<GUID, std::string> MissingTypeServerPDBs;
};
}
@@ -326,21 +326,22 @@ tryToLoadPDB(const GUID &GuidFromObj, StringRef TSPath) {
// PDB file doesn't mean it matches. For it to match the InfoStream's GUID
// must match the GUID specified in the TypeServer2 record.
if (ExpectedInfo->getGuid() != GuidFromObj)
- return make_error<pdb::PDBError>(
- pdb::pdb_error_code::type_server_not_found, TSPath);
+ return make_error<pdb::PDBError>(pdb::pdb_error_code::signature_out_of_date);
return std::move(NS);
}
Expected<const CVIndexMap&> PDBLinker::maybeMergeTypeServerPDB(ObjFile *File,
TypeServer2Record &TS) {
- const GUID& TSId = TS.getGuid();
+ const GUID &TSId = TS.getGuid();
StringRef TSPath = TS.getName();
// First, check if the PDB has previously failed to load.
- if (MissingTypeServerPDBs.count(TSId))
- return make_error<pdb::PDBError>(
- pdb::pdb_error_code::type_server_not_found, TSPath);
+ auto PrevErr = MissingTypeServerPDBs.find(TSId);
+ if (PrevErr != MissingTypeServerPDBs.end())
+ return createFileError(
+ TSPath, std::move(make_error<StringError>(PrevErr->second,
+ inconvertibleErrorCode())));
// Second, check if we already loaded a PDB with this GUID. Return the type
// index mapping if we have it.
@@ -355,20 +356,37 @@ Expected<const CVIndexMap&> PDBLinker::maybeMergeTypeServerPDB(ObjFile *File,
// Check for a PDB at:
// 1. The given file path
// 2. Next to the object file or archive file
- auto ExpectedSession = tryToLoadPDB(TSId, TSPath);
- if (!ExpectedSession) {
- consumeError(ExpectedSession.takeError());
- StringRef LocalPath =
- !File->ParentName.empty() ? File->ParentName : File->getName();
- SmallString<128> Path = sys::path::parent_path(LocalPath);
- sys::path::append(
- Path, sys::path::filename(TSPath, sys::path::Style::windows));
- ExpectedSession = tryToLoadPDB(TSId, Path);
- }
+ auto ExpectedSession = handleExpected(
+ tryToLoadPDB(TSId, TSPath),
+ [&]() {
+ StringRef LocalPath =
+ !File->ParentName.empty() ? File->ParentName : File->getName();
+ SmallString<128> Path = sys::path::parent_path(LocalPath);
+ sys::path::append(
+ Path, sys::path::filename(TSPath, sys::path::Style::windows));
+ return tryToLoadPDB(TSId, Path);
+ },
+ [&](std::unique_ptr<ECError> EC) -> Error {
+ auto SysErr = EC->convertToErrorCode();
+ // Only re-try loading if the previous error was "No such file or
+ // directory"
+ if (SysErr.category() == std::generic_category() &&
+ SysErr.value() == ENOENT)
+ return Error::success();
+ return Error(std::move(EC));
+ });
+
if (auto E = ExpectedSession.takeError()) {
TypeServerIndexMappings.erase(TSId);
- MissingTypeServerPDBs.emplace(TSId);
- return std::move(E);
+
+ // Flatten the error to a string, for later display, if the error occurs
+ // again on the same PDB.
+ std::string ErrMsg;
+ raw_string_ostream S(ErrMsg);
+ S << E;
+ auto It = MissingTypeServerPDBs.emplace(TSId, S.str());
+
+ return createFileError(TSPath, std::move(E));
}
pdb::NativeSession *Session = ExpectedSession->get();
@@ -837,8 +855,10 @@ void PDBLinker::addObjFile(ObjFile *File) {
// If the .debug$T sections fail to merge, assume there is no debug info.
if (!IndexMapResult) {
- warn("Type server PDB for " + Name + " is invalid, ignoring debug info. " +
- toString(IndexMapResult.takeError()));
+ auto FileName = sys::path::filename(Path);
+ warn("Cannot use debug info for '" + FileName + "'\n" +
+ ">>> failed to load reference " +
+ StringRef(toString(IndexMapResult.takeError())));
return;
}
OpenPOWER on IntegriCloud