From: Jordan Rupprecht Date: Mon, 11 Feb 2019 18:05:48 +0000 (+0000) Subject: [DebugInfo] Fix /usr/lib/debug llvm-symbolizer lookup with relative paths X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d3d623b47b69fd06656c2ae6c65e7f45b36759ad;p=llvm [DebugInfo] Fix /usr/lib/debug llvm-symbolizer lookup with relative paths Summary: rL189250 added a realpath call, and rL352916 because realpath breaks assumptions with some build systems. However, the /usr/lib/debug case has been clarified, falling back to /usr/lib/debug is currently broken if the obj passed in is a relative path. Adding a call to use absolute paths when falling back to /usr/lib/debug fixes that while still not making any realpath assumptions. This also adds a --fallback-debug-path command line flag for testing (since we probably can't write to /usr/lib/debug from buildbot environments), but was also verified manually: ``` $ rm -f path/to/dwarfdump-test.elf-x86-64 $ strace llvm-symbolizer --obj=relative/path/to/dwarfdump-test.elf-x86-64.debuglink 0x40113f |& grep dwarfdump ``` Lookups went to relative/path/to/dwarfdump-test.elf-x86-64, relative/path/to/.debug/dwarfdump-test.elf-x86-64, and then finally /usr/lib/debug/absolute/path/to/dwarfdump-test.elf-x86-64. Reviewers: dblaikie, samsonov Reviewed By: dblaikie Subscribers: krytarowski, aprantl, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D57916 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@353730 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/DebugInfo/Symbolize/Symbolize.h b/include/llvm/DebugInfo/Symbolize/Symbolize.h index 9b748a570c6..4e57fe43847 100644 --- a/include/llvm/DebugInfo/Symbolize/Symbolize.h +++ b/include/llvm/DebugInfo/Symbolize/Symbolize.h @@ -41,13 +41,16 @@ public: bool RelativeAddresses : 1; std::string DefaultArch; std::vector DsymHints; + std::string FallbackDebugPath; Options(FunctionNameKind PrintFunctions = FunctionNameKind::LinkageName, bool UseSymbolTable = true, bool Demangle = true, - bool RelativeAddresses = false, std::string DefaultArch = "") + bool RelativeAddresses = false, std::string DefaultArch = "", + std::string FallbackDebugPath = "") : PrintFunctions(PrintFunctions), UseSymbolTable(UseSymbolTable), Demangle(Demangle), RelativeAddresses(RelativeAddresses), - DefaultArch(std::move(DefaultArch)) {} + DefaultArch(std::move(DefaultArch)), + FallbackDebugPath(std::move(FallbackDebugPath)) {} }; LLVMSymbolizer(const Options &Opts = Options()) : Opts(Opts) {} diff --git a/lib/DebugInfo/Symbolize/Symbolize.cpp b/lib/DebugInfo/Symbolize/Symbolize.cpp index 5f7370c9ae5..73fe9780f52 100644 --- a/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -165,30 +165,40 @@ bool checkFileCRC(StringRef Path, uint32_t CRCHash) { bool findDebugBinary(const std::string &OrigPath, const std::string &DebuglinkName, uint32_t CRCHash, + const std::string &FallbackDebugPath, std::string &Result) { SmallString<16> OrigDir(OrigPath); llvm::sys::path::remove_filename(OrigDir); SmallString<16> DebugPath = OrigDir; - // Try /path/to/original_binary/debuglink_name + // Try relative/path/to/original_binary/debuglink_name llvm::sys::path::append(DebugPath, DebuglinkName); if (checkFileCRC(DebugPath, CRCHash)) { Result = DebugPath.str(); return true; } - // Try /path/to/original_binary/.debug/debuglink_name + // Try relative/path/to/original_binary/.debug/debuglink_name DebugPath = OrigDir; llvm::sys::path::append(DebugPath, ".debug", DebuglinkName); if (checkFileCRC(DebugPath, CRCHash)) { Result = DebugPath.str(); return true; } + // Make the path absolute so that lookups will go to + // "/usr/lib/debug/full/path/to/debug", not + // "/usr/lib/debug/to/debug" + llvm::sys::fs::make_absolute(OrigDir); + if (!FallbackDebugPath.empty()) { + // Try /absolute/path/to/original_binary/debuglink_name + DebugPath = FallbackDebugPath; + } else { #if defined(__NetBSD__) - // Try /usr/libdata/debug/path/to/original_binary/debuglink_name - DebugPath = "/usr/libdata/debug"; + // Try /usr/libdata/debug/absolute/path/to/original_binary/debuglink_name + DebugPath = "/usr/libdata/debug"; #else - // Try /usr/lib/debug/path/to/original_binary/debuglink_name - DebugPath = "/usr/lib/debug"; + // Try /usr/lib/debug/absolute/path/to/original_binary/debuglink_name + DebugPath = "/usr/lib/debug"; #endif + } llvm::sys::path::append(DebugPath, llvm::sys::path::relative_path(OrigDir), DebuglinkName); if (checkFileCRC(DebugPath, CRCHash)) { @@ -274,7 +284,8 @@ ObjectFile *LLVMSymbolizer::lookUpDebuglinkObject(const std::string &Path, std::string DebugBinaryPath; if (!getGNUDebuglinkContents(Obj, DebuglinkName, CRCHash)) return nullptr; - if (!findDebugBinary(Path, DebuglinkName, CRCHash, DebugBinaryPath)) + if (!findDebugBinary(Path, DebuglinkName, CRCHash, Opts.FallbackDebugPath, + DebugBinaryPath)) return nullptr; auto DbgObjOrErr = getOrCreateObject(DebugBinaryPath, ArchName); if (!DbgObjOrErr) { diff --git a/test/DebugInfo/symbolize-gnu-debuglink-fallback.test b/test/DebugInfo/symbolize-gnu-debuglink-fallback.test new file mode 100644 index 00000000000..43d5a2c818f --- /dev/null +++ b/test/DebugInfo/symbolize-gnu-debuglink-fallback.test @@ -0,0 +1,22 @@ +# REQUIRES: shell +# Ensures that .debuglink can fallback to a separate location. This is normally +# /usr/lib/debug (or /usr/libdata/debug for NetBSD), but can be configured on +# the command line (mainly for testing). + +RUN: rm -rf %t/foo %t/bar +RUN: mkdir -p %t/foo %t/bar/%t/foo + +RUN: cp %p/Inputs/dwarfdump-test.elf-x86-64.debuglink %t/foo + +RUN: llvm-symbolizer --obj=%t/foo/dwarfdump-test.elf-x86-64.debuglink 0x40113f \ +RUN: --fallback-debug-path=%t/bar | FileCheck %s --check-prefix=UNKNOWN + +UNKNOWN: main +UNKNOWN-NEXT: ??:0:0 + +RUN: cp %p/Inputs/dwarfdump-test.elf-x86-64 %t/bar/%t/foo +RUN: llvm-symbolizer --obj=%t/foo/dwarfdump-test.elf-x86-64.debuglink 0x40113f \ +RUN: --fallback-debug-path=%t/bar | FileCheck %s --check-prefix=FOUND + +FOUND: main +FOUND-NEXT: /tmp/dbginfo{{[/\\]}}dwarfdump-test.cc:16 diff --git a/tools/llvm-symbolizer/llvm-symbolizer.cpp b/tools/llvm-symbolizer/llvm-symbolizer.cpp index 0b0b8a68a4a..8ff7a22a71a 100644 --- a/tools/llvm-symbolizer/llvm-symbolizer.cpp +++ b/tools/llvm-symbolizer/llvm-symbolizer.cpp @@ -143,6 +143,10 @@ static cl::list ClInputAddresses(cl::Positional, cl::desc("..."), cl::ZeroOrMore); +static cl::opt + ClFallbackDebugPath("fallback-debug-path", cl::init(""), + cl::desc("Fallback path for debug binaries.")); + template static bool error(Expected &ResOrErr) { if (ResOrErr) @@ -234,7 +238,8 @@ int main(int argc, char **argv) { ClDemangle = !ClNoDemangle; LLVMSymbolizer::Options Opts(ClPrintFunctions, ClUseSymbolTable, ClDemangle, - ClUseRelativeAddress, ClDefaultArch); + ClUseRelativeAddress, ClDefaultArch, + ClFallbackDebugPath); for (const auto &hint : ClDsymHint) { if (sys::path::extension(hint) == ".dSYM") {