[llvm] 072e07a - [llvm-cov] Optionally fail on missing binary ID

Daniel Thornburgh via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 3 10:24:25 PST 2023


Author: Daniel Thornburgh
Date: 2023-03-03T10:24:21-08:00
New Revision: 072e07a9d5928fd3b1c1dabeac82890713ce172b

URL: https://github.com/llvm/llvm-project/commit/072e07a9d5928fd3b1c1dabeac82890713ce172b
DIFF: https://github.com/llvm/llvm-project/commit/072e07a9d5928fd3b1c1dabeac82890713ce172b.diff

LOG: [llvm-cov] Optionally fail on missing binary ID

This adds the --check-binary-id flag that makes sure that an object file
is available for every binary ID mentioned in the given profile. This
should help make the tool more robust in CI environments where it's
expected that coverage mappings should be available for every object
contributing to the profile.

Reviewed By: gulfem

Differential Revision: https://reviews.llvm.org/D144308

Added: 
    

Modified: 
    compiler-rt/test/profile/Linux/binary-id-lookup.c
    llvm/docs/CommandGuide/llvm-cov.rst
    llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
    llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
    llvm/tools/llvm-cov/CodeCoverage.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/test/profile/Linux/binary-id-lookup.c b/compiler-rt/test/profile/Linux/binary-id-lookup.c
index 662fdcfb32a39..1496e70d96b2c 100644
--- a/compiler-rt/test/profile/Linux/binary-id-lookup.c
+++ b/compiler-rt/test/profile/Linux/binary-id-lookup.c
@@ -8,12 +8,20 @@
 // 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) {}
@@ -21,6 +29,7 @@
 // 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

diff  --git a/llvm/docs/CommandGuide/llvm-cov.rst b/llvm/docs/CommandGuide/llvm-cov.rst
index ecbb0d2a2ec57..c4692b3c1e8f9 100644
--- a/llvm/docs/CommandGuide/llvm-cov.rst
+++ b/llvm/docs/CommandGuide/llvm-cov.rst
@@ -360,6 +360,11 @@ is compiled in and configured via the DEBUGINFOD_URLS environment variable.
 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:
@@ -441,6 +446,11 @@ DEBUGINFOD_URLS.
 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:
@@ -527,3 +537,8 @@ DEBUGINFOD_URLS.
 
 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.

diff  --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
index 37ddae87d5742..3c8f940ba97b7 100644
--- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
+++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
@@ -622,7 +622,8 @@ class CoverageMapping {
   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.
   ///

diff  --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
index 360d30d5d0a14..d6aec276838e6 100644
--- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
+++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
@@ -15,7 +15,9 @@
 #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"
@@ -382,11 +384,10 @@ Error CoverageMapping::loadFromFile(
   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));
@@ -430,13 +431,19 @@ CoverageMapping::load(ArrayRef<StringRef> ObjectFilenames,
 
     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)));
+      }
     }
   }
 

diff  --git a/llvm/tools/llvm-cov/CodeCoverage.cpp b/llvm/tools/llvm-cov/CodeCoverage.cpp
index a7518a3e441a7..02448dcd31a16 100644
--- a/llvm/tools/llvm-cov/CodeCoverage.cpp
+++ b/llvm/tools/llvm-cov/CodeCoverage.cpp
@@ -185,6 +185,8 @@ class CodeCoverageTool {
   std::unique_ptr<SpecialCaseList> NameAllowlist;
 
   std::unique_ptr<object::BuildIDFetcher> BIDFetcher;
+
+  bool CheckBinaryIDs;
 };
 }
 
@@ -440,9 +442,9 @@ std::unique_ptr<CoverageMapping> CodeCoverageTool::load() {
       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;
@@ -761,6 +763,10 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
       "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;
@@ -770,6 +776,7 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
     } else {
       BIDFetcher = std::make_unique<object::BuildIDFetcher>(DebugFileDirectory);
     }
+    this->CheckBinaryIDs = CheckBinaryIDs;
 
     if (!CovFilename.empty())
       ObjectFilenames.emplace_back(CovFilename);


        


More information about the llvm-commits mailing list