[llvm] [llvm] Errorize DebuginfodFetcher::fetch() for inspection at call-sites (NFC) (PR #191191)

Stefan Gränitz via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 15 03:53:01 PDT 2026


https://github.com/weliveindetail updated https://github.com/llvm/llvm-project/pull/191191

>From e609b60d6495bd203b3365128100556fad241a8a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20Gr=C3=A4nitz?= <stefan.graenitz at gmail.com>
Date: Thu, 9 Apr 2026 15:23:00 +0200
Subject: [PATCH 1/2] [llvm] Errorize DebuginfodFetcher::fetch() so users can
 inspect errors (NFC)

---
 llvm/include/llvm/Debuginfod/BuildIDFetcher.h        |  3 +--
 llvm/include/llvm/Object/BuildID.h                   |  3 ++-
 llvm/lib/DebugInfo/Symbolize/Symbolize.cpp           |  5 +++--
 llvm/lib/Debuginfod/BuildIDFetcher.cpp               | 12 +++++-------
 llvm/lib/Object/BuildID.cpp                          |  8 ++++++--
 llvm/lib/ProfileData/Coverage/CoverageMapping.cpp    | 12 +++++++-----
 llvm/lib/ProfileData/InstrProfCorrelator.cpp         |  7 ++++---
 .../llvm-debuginfod-find/llvm-debuginfod-find.cpp    | 10 ++++++----
 llvm/tools/llvm-objdump/llvm-objdump.cpp             |  9 ++++++---
 9 files changed, 40 insertions(+), 29 deletions(-)

diff --git a/llvm/include/llvm/Debuginfod/BuildIDFetcher.h b/llvm/include/llvm/Debuginfod/BuildIDFetcher.h
index 8f9c2aa8722ad..66b6720a01226 100644
--- a/llvm/include/llvm/Debuginfod/BuildIDFetcher.h
+++ b/llvm/include/llvm/Debuginfod/BuildIDFetcher.h
@@ -16,7 +16,6 @@
 #define LLVM_DEBUGINFOD_DIFETCHER_H
 
 #include "llvm/Object/BuildID.h"
-#include <optional>
 
 namespace llvm {
 
@@ -28,7 +27,7 @@ class DebuginfodFetcher : public object::BuildIDFetcher {
 
   /// Fetches the given Build ID using debuginfod and returns a local path to
   /// the resulting file.
-  std::optional<std::string> fetch(object::BuildIDRef BuildID) const override;
+  Expected<std::string> fetch(object::BuildIDRef BuildID) const override;
 };
 
 } // namespace llvm
diff --git a/llvm/include/llvm/Object/BuildID.h b/llvm/include/llvm/Object/BuildID.h
index 65ba00f75dd6f..73b1a0784da13 100644
--- a/llvm/include/llvm/Object/BuildID.h
+++ b/llvm/include/llvm/Object/BuildID.h
@@ -18,6 +18,7 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Compiler.h"
+#include "llvm/Support/Error.h"
 
 namespace llvm {
 namespace object {
@@ -44,7 +45,7 @@ class LLVM_ABI BuildIDFetcher {
   virtual ~BuildIDFetcher() = default;
 
   /// Returns the path to the debug file with the given build ID.
-  virtual std::optional<std::string> fetch(BuildIDRef BuildID) const;
+  virtual Expected<std::string> fetch(BuildIDRef BuildID) const;
 
 private:
   const std::vector<std::string> DebugFileDirectories;
diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
index 3821f53d26b98..0a36340c82ab0 100644
--- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
+++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
@@ -490,14 +490,15 @@ bool LLVMSymbolizer::getOrFindDebugBinary(const ArrayRef<uint8_t> BuildID,
   }
   if (!BIDFetcher)
     return false;
-  if (std::optional<std::string> Path = BIDFetcher->fetch(BuildID)) {
+  Expected<std::string> Path = BIDFetcher->fetch(BuildID);
+  if (Path) {
     Result = *Path;
     auto InsertResult = BuildIDPaths.insert({BuildIDStr, Result});
     assert(InsertResult.second);
     (void)InsertResult;
     return true;
   }
-
+  consumeError(Path.takeError());
   return false;
 }
 
diff --git a/llvm/lib/Debuginfod/BuildIDFetcher.cpp b/llvm/lib/Debuginfod/BuildIDFetcher.cpp
index a7f13104abee1..3d0161d25602a 100644
--- a/llvm/lib/Debuginfod/BuildIDFetcher.cpp
+++ b/llvm/lib/Debuginfod/BuildIDFetcher.cpp
@@ -18,14 +18,12 @@
 
 using namespace llvm;
 
-std::optional<std::string>
+Expected<std::string>
 DebuginfodFetcher::fetch(ArrayRef<uint8_t> BuildID) const {
-  if (std::optional<std::string> Path = BuildIDFetcher::fetch(BuildID))
+  if (Expected<std::string> Path = BuildIDFetcher::fetch(BuildID))
     return std::move(*Path);
+  else
+    consumeError(Path.takeError());
 
-  Expected<std::string> PathOrErr = getCachedOrDownloadDebuginfo(BuildID);
-  if (PathOrErr)
-    return *PathOrErr;
-  consumeError(PathOrErr.takeError());
-  return std::nullopt;
+  return getCachedOrDownloadDebuginfo(BuildID);
 }
diff --git a/llvm/lib/Object/BuildID.cpp b/llvm/lib/Object/BuildID.cpp
index d1ee597a11327..591c3a41e1df7 100644
--- a/llvm/lib/Object/BuildID.cpp
+++ b/llvm/lib/Object/BuildID.cpp
@@ -15,6 +15,7 @@
 #include "llvm/Object/BuildID.h"
 
 #include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Support/Error.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
 
@@ -79,7 +80,7 @@ BuildIDRef llvm::object::getBuildID(const ObjectFile *Obj) {
   return {};
 }
 
-std::optional<std::string> BuildIDFetcher::fetch(BuildIDRef BuildID) const {
+Expected<std::string> BuildIDFetcher::fetch(BuildIDRef BuildID) const {
   auto GetDebugPath = [&](StringRef Directory) {
     SmallString<128> Path{Directory};
     sys::path::append(Path, ".build-id",
@@ -108,5 +109,8 @@ std::optional<std::string> BuildIDFetcher::fetch(BuildIDRef BuildID) const {
         return std::string(Path);
     }
   }
-  return std::nullopt;
+  return createStringError(
+      make_error_code(std::errc::no_such_file_or_directory),
+      "could not find debug file for build ID '" +
+          llvm::toHex(BuildID, /*LowerCase=*/true) + "'");
 }
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
index 0d9a5a6758f06..3ec932f62dc85 100644
--- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
+++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
@@ -1106,19 +1106,21 @@ Expected<std::unique_ptr<CoverageMapping>> CoverageMapping::load(
     }
 
     for (object::BuildIDRef BinaryID : BinaryIDsToFetch) {
-      std::optional<std::string> PathOpt = BIDFetcher->fetch(BinaryID);
-      if (PathOpt) {
-        std::string Path = std::move(*PathOpt);
+      Expected<std::string> Path = BIDFetcher->fetch(BinaryID);
+      if (Path) {
         StringRef Arch = Arches.size() == 1 ? Arches.front() : StringRef();
-        if (Error E = loadFromFile(Path, Arch, CompilationDir, ProfileReaderRef,
-                                   *Coverage, DataFound))
+        if (Error E = loadFromFile(*Path, Arch, CompilationDir,
+                                   ProfileReaderRef, *Coverage, DataFound))
           return std::move(E);
       } else if (CheckBinaryIDs) {
+        consumeError(Path.takeError());
         return createFileError(
             ProfileFilename.value(),
             createStringError(errc::no_such_file_or_directory,
                               "Missing binary ID: " +
                                   llvm::toHex(BinaryID, /*LowerCase=*/true)));
+      } else {
+        consumeError(Path.takeError());
       }
     }
   }
diff --git a/llvm/lib/ProfileData/InstrProfCorrelator.cpp b/llvm/lib/ProfileData/InstrProfCorrelator.cpp
index b38189de31606..6993e72af476b 100644
--- a/llvm/lib/ProfileData/InstrProfCorrelator.cpp
+++ b/llvm/lib/ProfileData/InstrProfCorrelator.cpp
@@ -114,7 +114,6 @@ llvm::Expected<std::unique_ptr<InstrProfCorrelator>>
 InstrProfCorrelator::get(StringRef Filename, ProfCorrelatorKind FileKind,
                          const object::BuildIDFetcher *BIDFetcher,
                          const ArrayRef<object::BuildID> BIs) {
-  std::optional<std::string> Path;
   if (BIDFetcher) {
     if (BIs.empty())
       return make_error<InstrProfError>(
@@ -127,12 +126,14 @@ InstrProfCorrelator::get(StringRef Filename, ProfCorrelatorKind FileKind,
           "unsupported profile binary correlation when there are multiple "
           "build IDs in a profile");
 
-    Path = BIDFetcher->fetch(BIs.front());
-    if (!Path)
+    Expected<std::string> Path = BIDFetcher->fetch(BIs.front());
+    if (!Path) {
+      consumeError(Path.takeError());
       return make_error<InstrProfError>(
           instrprof_error::unable_to_correlate_profile,
           "Missing build ID: " + llvm::toHex(BIs.front(),
                                              /*LowerCase=*/true));
+    }
     Filename = *Path;
   }
 
diff --git a/llvm/tools/llvm-debuginfod-find/llvm-debuginfod-find.cpp b/llvm/tools/llvm-debuginfod-find/llvm-debuginfod-find.cpp
index 8f1b9d0f4659d..a2658fdd9f74e 100644
--- a/llvm/tools/llvm-debuginfod-find/llvm-debuginfod-find.cpp
+++ b/llvm/tools/llvm-debuginfod-find/llvm-debuginfod-find.cpp
@@ -152,10 +152,12 @@ int llvm_debuginfod_find_main(int argc, char **argv,
 
 // Find a debug file in local build ID directories and via debuginfod.
 std::string fetchDebugInfo(object::BuildIDRef BuildID) {
-  if (std::optional<std::string> Path =
-          DebuginfodFetcher(DebugFileDirectory).fetch(BuildID))
-    return *Path;
-  errs() << "Build ID " << llvm::toHex(BuildID, /*Lowercase=*/true)
+  Expected<std::string> PathOrErr =
+      DebuginfodFetcher(DebugFileDirectory).fetch(BuildID);
+  if (PathOrErr)
+    return *PathOrErr;
+  errs() << "Build ID " << llvm::toHex(BuildID, /*Lowercase=*/true) << ": "
          << " could not be found.\n";
+  consumeError(PathOrErr.takeError());
   exit(1);
 }
diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp
index 776e9c6e2f89f..504860ac41dea 100644
--- a/llvm/tools/llvm-objdump/llvm-objdump.cpp
+++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp
@@ -1743,9 +1743,11 @@ fetchBinaryByBuildID(const ObjectFile &Obj) {
   object::BuildIDRef BuildID = getBuildID(&Obj);
   if (BuildID.empty())
     return std::nullopt;
-  std::optional<std::string> Path = BIDFetcher->fetch(BuildID);
-  if (!Path)
+  Expected<std::string> Path = BIDFetcher->fetch(BuildID);
+  if (!Path) {
+    consumeError(Path.takeError());
     return std::nullopt;
+  }
   Expected<OwningBinary<Binary>> DebugBinary = createBinary(*Path);
   if (!DebugBinary) {
     reportWarning(toString(DebugBinary.takeError()), *Path);
@@ -3840,8 +3842,9 @@ static void parseObjdumpOptions(const llvm::opt::InputArgList &InputArgs) {
   // Look up any provided build IDs, then append them to the input filenames.
   for (const opt::Arg *A : InputArgs.filtered(OBJDUMP_build_id)) {
     object::BuildID BuildID = parseBuildIDArg(A);
-    std::optional<std::string> Path = BIDFetcher->fetch(BuildID);
+    Expected<std::string> Path = BIDFetcher->fetch(BuildID);
     if (!Path) {
+      consumeError(Path.takeError());
       reportCmdLineError(A->getSpelling() + ": could not find build ID '" +
                          A->getValue() + "'");
     }

>From 2013a9e5b16d607d661c1b6154621bf528aabd1d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20Gr=C3=A4nitz?= <stefan.graenitz at gmail.com>
Date: Wed, 15 Apr 2026 12:52:13 +0200
Subject: [PATCH 2/2] Address feedback

---
 llvm/lib/Debuginfod/BuildIDFetcher.cpp            | 13 ++++++++-----
 llvm/lib/ProfileData/Coverage/CoverageMapping.cpp |  3 +--
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/Debuginfod/BuildIDFetcher.cpp b/llvm/lib/Debuginfod/BuildIDFetcher.cpp
index 3d0161d25602a..8beb7a88af992 100644
--- a/llvm/lib/Debuginfod/BuildIDFetcher.cpp
+++ b/llvm/lib/Debuginfod/BuildIDFetcher.cpp
@@ -15,15 +15,18 @@
 #include "llvm/Debuginfod/BuildIDFetcher.h"
 
 #include "llvm/Debuginfod/Debuginfod.h"
+#include "llvm/Support/Error.h"
 
 using namespace llvm;
 
 Expected<std::string>
 DebuginfodFetcher::fetch(ArrayRef<uint8_t> BuildID) const {
-  if (Expected<std::string> Path = BuildIDFetcher::fetch(BuildID))
-    return std::move(*Path);
-  else
-    consumeError(Path.takeError());
-
+  Expected<std::string> Path = BuildIDFetcher::fetch(BuildID);
+  if (Path)
+    return Path;
+  assert(errorToErrorCode(Path.takeError()) ==
+             std::errc::no_such_file_or_directory &&
+         "BuildIDFetcher::fetch() failed in an unexpected way");
+  consumeError(Path.takeError());
   return getCachedOrDownloadDebuginfo(BuildID);
 }
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
index 3ec932f62dc85..1ab2eba3758ae 100644
--- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
+++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
@@ -1106,8 +1106,7 @@ Expected<std::unique_ptr<CoverageMapping>> CoverageMapping::load(
     }
 
     for (object::BuildIDRef BinaryID : BinaryIDsToFetch) {
-      Expected<std::string> Path = BIDFetcher->fetch(BinaryID);
-      if (Path) {
+      if (Expected<std::string> Path = BIDFetcher->fetch(BinaryID)) {
         StringRef Arch = Arches.size() == 1 ? Arches.front() : StringRef();
         if (Error E = loadFromFile(*Path, Arch, CompilationDir,
                                    ProfileReaderRef, *Coverage, DataFound))



More information about the llvm-commits mailing list