// RUN: cp %t/libfoo.so %t/.build-id/12/345678.debug
// RUN: cp %t.main %t/.build-id/ab/cd1234.debug
// RUN: llvm-profdata merge -o %t.profdata %t.profdir/default_*.profraw
+
// RUN: llvm-cov show -instr-profile %t.profdata -debug-file-directory %t | FileCheck %s
// RUN: llvm-cov show -instr-profile %t.profdata %t/libfoo.so -sources %t/foo.c -object %t.main | FileCheck %s --check-prefix=FOO-ONLY
// RUN: llvm-cov show -instr-profile %t.profdata -debug-file-directory %t -sources %t/foo.c | FileCheck %s --check-prefix=FOO-ONLY
// RUN: llvm-cov show -instr-profile %t.profdata -debug-file-directory %t %t/libfoo.so -sources %t/foo.c | FileCheck %s --check-prefix=FOO-ONLY
+
+// RUN: rm %t/.build-id/ab/cd1234.debug
+// RUN: llvm-cov show -instr-profile %t.profdata -debug-file-directory %t %t.main | FileCheck %s
+// RUN: llvm-cov show -instr-profile %t.profdata -debug-file-directory %t | FileCheck %s --check-prefix=FOO-ONLY
+// RUN: not llvm-cov show -instr-profile %t.profdata -debug-file-directory %t --check-binary-ids 2>&1 | FileCheck %s --check-prefix=MISSING-BINARY-ID -DFILENAME=%t.profdata
+
// RUN: echo "bad" > %t/.build-id/ab/cd1234.debug
// RUN: llvm-cov show -instr-profile %t.profdata -debug-file-directory %t %t.main | FileCheck %s
+
// RUN: not llvm-cov show -instr-profile %t.profdata -debug-file-directory %t/empty 2>&1 | FileCheck %s --check-prefix=NODATA
// CHECK: 1| 1|void foo(void) {}
// CHECK: 3| 1|int main() {
// FOO-ONLY: 1| 1|void foo(void) {}
+// MISSING-BINARY-ID: error: Failed to load coverage: '[[FILENAME]]': Missing binary ID: abcd1234
// NODATA: error: Failed to load coverage: '': No coverage data found
//--- foo.c
Provides local directories to search for objects corresponding to binary IDs in
the profile (as with debuginfod). Defaults to system build ID directories.
+.. option:: -check-binary-id
+
+Fail if an object file cannot be found for a binary ID present in the profile,
+neither on the command line nor via binary ID lookup.
+
.. program:: llvm-cov report
.. _llvm-cov-report:
Provides a directory to search for objects corresponding to binary IDs in the
profile.
+.. option:: -check-binary-id
+
+Fail if an object file cannot be found for a binary ID present in the profile,
+neither on the command line nor via binary ID lookup.
+
.. program:: llvm-cov export
.. _llvm-cov-export:
Provides a directory to search for objects corresponding to binary IDs in the
profile.
+
+.. option:: -check-binary-id
+
+Fail if an object file cannot be found for a binary ID present in the profile,
+neither on the command line nor via binary ID lookup.
load(ArrayRef<StringRef> ObjectFilenames, StringRef ProfileFilename,
vfs::FileSystem &FS, ArrayRef<StringRef> Arches = std::nullopt,
StringRef CompilationDir = "",
- const object::BuildIDFetcher *BIDFetcher = nullptr);
+ const object::BuildIDFetcher *BIDFetcher = nullptr,
+ bool CheckBinaryIDs = false);
/// The number of functions that couldn't have their profiles mapped.
///
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallBitVector.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Object/BuildID.h"
#include "llvm/ProfileData/Coverage/CoverageMappingReader.h"
return Error::success();
}
-Expected<std::unique_ptr<CoverageMapping>>
-CoverageMapping::load(ArrayRef<StringRef> ObjectFilenames,
- StringRef ProfileFilename, vfs::FileSystem &FS,
- ArrayRef<StringRef> Arches, StringRef CompilationDir,
- const object::BuildIDFetcher *BIDFetcher) {
+Expected<std::unique_ptr<CoverageMapping>> CoverageMapping::load(
+ ArrayRef<StringRef> ObjectFilenames, StringRef ProfileFilename,
+ vfs::FileSystem &FS, ArrayRef<StringRef> Arches, StringRef CompilationDir,
+ const object::BuildIDFetcher *BIDFetcher, bool CheckBinaryIDs) {
auto ProfileReaderOrErr = IndexedInstrProfReader::create(ProfileFilename, FS);
if (Error E = ProfileReaderOrErr.takeError())
return createFileError(ProfileFilename, std::move(E));
for (object::BuildIDRef BinaryID : BinaryIDsToFetch) {
std::optional<std::string> PathOpt = BIDFetcher->fetch(BinaryID);
- if (!PathOpt)
- continue;
- std::string Path = std::move(*PathOpt);
- StringRef Arch = Arches.size() == 1 ? Arches.front() : StringRef();
- if (Error E = loadFromFile(Path, Arch, CompilationDir, *ProfileReader,
- *Coverage, DataFound))
- return std::move(E);
+ if (PathOpt) {
+ std::string Path = std::move(*PathOpt);
+ StringRef Arch = Arches.size() == 1 ? Arches.front() : StringRef();
+ if (Error E = loadFromFile(Path, Arch, CompilationDir, *ProfileReader,
+ *Coverage, DataFound))
+ return std::move(E);
+ } else if (CheckBinaryIDs) {
+ return createFileError(
+ ProfileFilename,
+ createStringError(errc::no_such_file_or_directory,
+ "Missing binary ID: " +
+ llvm::toHex(BinaryID, /*LowerCase=*/true)));
+ }
}
}
std::unique_ptr<SpecialCaseList> NameAllowlist;
std::unique_ptr<object::BuildIDFetcher> BIDFetcher;
+
+ bool CheckBinaryIDs;
};
}
warning("profile data may be out of date - object is newer",
ObjectFilename);
auto FS = vfs::getRealFileSystem();
- auto CoverageOrErr =
- CoverageMapping::load(ObjectFilenames, PGOFilename, *FS, CoverageArches,
- ViewOpts.CompilationDirectory, BIDFetcher.get());
+ auto CoverageOrErr = CoverageMapping::load(
+ ObjectFilenames, PGOFilename, *FS, CoverageArches,
+ ViewOpts.CompilationDirectory, BIDFetcher.get(), CheckBinaryIDs);
if (Error E = CoverageOrErr.takeError()) {
error("Failed to load coverage: " + toString(std::move(E)));
return nullptr;
"compilation-dir", cl::init(""),
cl::desc("Directory used as a base for relative coverage mapping paths"));
+ cl::opt<bool> CheckBinaryIDs(
+ "check-binary-ids", cl::desc("Fail if an object couldn't be found for a "
+ "binary ID in the profile"));
+
auto commandLineParser = [&, this](int argc, const char **argv) -> int {
cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n");
ViewOpts.Debug = DebugDump;
} else {
BIDFetcher = std::make_unique<object::BuildIDFetcher>(DebugFileDirectory);
}
+ this->CheckBinaryIDs = CheckBinaryIDs;
if (!CovFilename.empty())
ObjectFilenames.emplace_back(CovFilename);