Skip to content

Commit

Permalink
[DebugInfo] Fix /usr/lib/debug llvm-symbolizer lookup with relative p…
Browse files Browse the repository at this point in the history
…aths

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

llvm-svn: 353730
  • Loading branch information
rupprecht committed Feb 11, 2019
1 parent 2e12dce commit 5b7ad42
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 10 deletions.
7 changes: 5 additions & 2 deletions llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h
Expand Up @@ -41,13 +41,16 @@ class LLVMSymbolizer {
bool RelativeAddresses : 1;
std::string DefaultArch;
std::vector<std::string> 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) {}
Expand Down
25 changes: 18 additions & 7 deletions llvm/lib/DebugInfo/Symbolize/Symbolize.cpp
Expand Up @@ -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 <FallbackDebugPath>/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)) {
Expand Down Expand Up @@ -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) {
Expand Down
22 changes: 22 additions & 0 deletions llvm/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
7 changes: 6 additions & 1 deletion llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp
Expand Up @@ -143,6 +143,10 @@ static cl::list<std::string> ClInputAddresses(cl::Positional,
cl::desc("<input addresses>..."),
cl::ZeroOrMore);

static cl::opt<std::string>
ClFallbackDebugPath("fallback-debug-path", cl::init(""),
cl::desc("Fallback path for debug binaries."));

template<typename T>
static bool error(Expected<T> &ResOrErr) {
if (ResOrErr)
Expand Down Expand Up @@ -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") {
Expand Down

0 comments on commit 5b7ad42

Please sign in to comment.