diff --git a/llvm/docs/CommandGuide/llvm-symbolizer.rst b/llvm/docs/CommandGuide/llvm-symbolizer.rst --- a/llvm/docs/CommandGuide/llvm-symbolizer.rst +++ b/llvm/docs/CommandGuide/llvm-symbolizer.rst @@ -188,6 +188,13 @@ Look up the object using the given build ID, specified as a hexadecimal string. Mutually exclusive with :option:`--obj`. +.. option:: --debuginfod, --no-debuginfod + + Whether or not to try debuginfod lookups for debug binaries. Unless specified, + debuginfod is only enabled if libcurl was compiled in (``LLVM_ENABLE_CURL``) + and at least one server URL was provided by the environment variable + ``DEBUGINFOD_URLS``. + .. _llvm-symbolizer-opt-C: .. option:: --demangle, -C diff --git a/llvm/test/tools/llvm-symbolizer/debuginfod.test b/llvm/test/tools/llvm-symbolizer/debuginfod.test --- a/llvm/test/tools/llvm-symbolizer/debuginfod.test +++ b/llvm/test/tools/llvm-symbolizer/debuginfod.test @@ -23,10 +23,15 @@ # The symbolizer should call the debuginfod client library, which finds the # debuginfo placed in the cache, enabling symbolization of the address. RUN: env DEBUGINFOD_CACHE_PATH=%t llvm-symbolizer \ -RUN: --obj=%t/addr.exe 0x40054d | FileCheck %s --check-prefix=FOUND +RUN: --obj=%t/addr.exe 0x40054d --debuginfod | \ +RUN: FileCheck %s --check-prefix=FOUND FOUND: {{[/\]+}}tmp{{[/\]+}}x.c:14:0 # This should also work if the build ID is provided. RUN: env DEBUGINFOD_CACHE_PATH=%t llvm-symbolizer \ RUN: --build-id=127da749021c1fc1a58cba734a1f542cbe2b7ce4 0x40054d | \ RUN: FileCheck %s --check-prefix=FOUND + +# The symbolizer shouldn't call the debuginfod library by default with no URLs. +RUN: env DEBUGINFOD_CACHE_PATH=%t llvm-symbolizer --print-address \ +RUN: --obj=%t/addr.exe 0x40054d | FileCheck %s --check-prefix=NOTFOUND diff --git a/llvm/tools/llvm-symbolizer/Opts.td b/llvm/tools/llvm-symbolizer/Opts.td --- a/llvm/tools/llvm-symbolizer/Opts.td +++ b/llvm/tools/llvm-symbolizer/Opts.td @@ -23,6 +23,7 @@ def basenames : Flag<["--"], "basenames">, HelpText<"Strip directory names from paths">; defm build_id : Eq<"build-id", "Build ID used to look up the object file">; defm debug_file_directory : Eq<"debug-file-directory", "Path to directory where to look for debug files">, MetaVarName<"">; +defm debuginfod : B<"debuginfod", "Use debuginfod to find debug binaries", "Don't use debuginfod to find debug binaries">; defm default_arch : Eq<"default-arch", "Default architecture (for multi-arch objects)">, Group; diff --git a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp --- a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp +++ b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp @@ -21,6 +21,7 @@ #include "llvm/DebugInfo/Symbolize/DIPrinter.h" #include "llvm/DebugInfo/Symbolize/Symbolize.h" #include "llvm/Debuginfod/DIFetcher.h" +#include "llvm/Debuginfod/Debuginfod.h" #include "llvm/Debuginfod/HTTPClient.h" #include "llvm/Option/Arg.h" #include "llvm/Option/ArgList.h" @@ -296,6 +297,27 @@ return {}; } +ExitOnError ExitOnErr; + +static bool shouldUseDebuginfodByDefault(ArrayRef BuildID) { + // If the user explicitly specified a build ID, the usual way to find it is + // debuginfod. + if (!BuildID.empty()) + return true; + + // A debuginfod lookup could succeed if a HTTP client is available and at + // least one backing URL is configured. + if (HTTPClient::isAvailable() && + !ExitOnErr(getDefaultDebuginfodUrls()).empty()) + return true; + + // A debuginfod lookup could also succeed if something were present in the + // cache directory, but it would be surprising to enable debuginfod on this + // basis alone. To use existing caches in an "offline" fashion, the debuginfod + // flag must be set. + return false; +} + int main(int argc, char **argv) { InitLLVM X(argc, argv); sys::InitializeCOMRAII COM(sys::COMThreadingMode::MultiThreaded); @@ -371,10 +393,13 @@ LLVMSymbolizer Symbolizer(Opts); - // Look up symbols using the debuginfod client. - Symbolizer.addDIFetcher(std::make_unique()); - // The HTTPClient must be initialized for use by the debuginfod client. - HTTPClient::initialize(); + if (Args.hasFlag(OPT_debuginfod, OPT_no_debuginfod, + shouldUseDebuginfodByDefault(BuildID))) { + // Look up symbols using the debuginfod client. + Symbolizer.addDIFetcher(std::make_unique()); + // The HTTPClient must be initialized for use by the debuginfod client. + HTTPClient::initialize(); + } std::unique_ptr Printer; if (Style == OutputStyle::GNU)