diff options
| author | Alexandre Ganea <alexandre.ganea@ubisoft.com> | 2018-09-10 13:51:21 +0000 |
|---|---|---|
| committer | Alexandre Ganea <alexandre.ganea@ubisoft.com> | 2018-09-10 13:51:21 +0000 |
| commit | d93b07f0b09c55bb7e01b463a822b214d141d6a8 (patch) | |
| tree | 158c18b2a37a24b45b1628fab72886f039f6b99e /lld/COFF/PDB.cpp | |
| parent | a32d253f10cb7dccf17ffaeaa037c6bef453a6d5 (diff) | |
| download | bcm5719-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.cpp | 62 |
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; } |

