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 @@ -28,6 +28,13 @@ input or as positional arguments on the command-line, following any "DATA" or "CODE" prefix. +Wherever a binary filename is accepted, a Build ID can be provided instead to +search for the binary. Various cache directories are searched first, followed by +any DebugInfoD servers configured via the ``DEBUGINFOD_URLS`` environment +variable. For server lookups to work, the tool needs must have been built with +``LLVM_ENABLE_CURL`` enabled. + + :program:`llvm-symbolizer` parses options from the environment variable ``LLVM_SYMBOLIZER_OPTS`` after parsing options from the command line. ``LLVM_SYMBOLIZER_OPTS`` is primarily useful for supplementing the command-line diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp --- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -508,9 +508,32 @@ Bin = Pair.first->second.getBinary(); } else { Expected> BinOrErr = createBinary(Path); - if (!BinOrErr) - return BinOrErr.takeError(); - Pair.first->second = std::move(BinOrErr.get()); + if (BinOrErr) { + Pair.first->second = std::move(BinOrErr.get()); + } else { + ArrayRef BuildID; + + // Since this isn't a path to a valid binary, maybe it's a Build ID. + std::string Bytes; + if (!tryGetFromHex(Path, Bytes)) + return BinOrErr.takeError(); + BuildID = ArrayRef( + reinterpret_cast(Bytes.data()), Bytes.size()); + // There's no fixed size for Build IDs, but if it's fewer than 128 bits, + // it's unlikely to be one. + if (BuildID.size() < 16) + return BinOrErr.takeError(); + + std::string PathFromBuildID; + if (!findDebugBinary(Opts.DebugFileDirectory, BuildID, PathFromBuildID)) + return BinOrErr.takeError(); + Expected> BuildIDBinOrErr = + createBinary(PathFromBuildID); + if (!BuildIDBinOrErr) + return joinErrors(BinOrErr.takeError(), BuildIDBinOrErr.takeError()); + consumeError(BinOrErr.takeError()); + Pair.first->second = std::move(BuildIDBinOrErr.get()); + } Bin = Pair.first->second.getBinary(); } 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 @@ -25,3 +25,8 @@ RUN: env DEBUGINFOD_CACHE_PATH=%t llvm-symbolizer \ RUN: --obj=%t/addr.exe 0x40054d | FileCheck %s --check-prefix=FOUND FOUND: {{[/\]+}}tmp{{[/\]+}}x.c:14:0 + +# This should also work if the Build ID is provided in lieu of a path. +RUN: env DEBUGINFOD_CACHE_PATH=%t llvm-symbolizer \ +RUN: --obj=127da749021c1fc1a58cba734a1f542cbe2b7ce4 0x40054d | \ +RUN: FileCheck %s --check-prefix=FOUND