From e5adb68e044da6733e9ebba7aea913c1ca9618dd Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Sun, 30 Jul 2017 01:34:08 +0000 Subject: [PATCH] DebugInfo: Provide option for explicitly specifying the name of the DWP file If you've archived the DWP file somewhere it's probably useful to be able to just tell llvm-symbolizer where it is when you're symbolizing stack traces from the binary. This only provides a mechanism for specifying a single DWP file, good if you're symbolizing a program with a single DWP file, but it's likely if the program is dynamically linked that you might have a DWP for each dynamic library - in which case this feature won't help (at least as it's surfaced in llvm-symbolizer for now) - in theory it could be extended to specify a collection of DWP files that could all be consulted for split CU hash resolution. llvm-svn: 309498 --- .../include/llvm/DebugInfo/DWARF/DWARFContext.h | 10 +++++++--- .../llvm/DebugInfo/Symbolize/Symbolize.h | 8 +++++--- llvm/lib/DebugInfo/DWARF/DWARFContext.cpp | 15 +++++++++------ llvm/lib/DebugInfo/Symbolize/Symbolize.cpp | 17 ++++++++++------- llvm/test/DebugInfo/llvm-symbolizer.test | 13 +++++++++---- llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp | 10 ++++++++-- 6 files changed, 48 insertions(+), 25 deletions(-) diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h index 18908ae24fe0..272f91cf954b 100644 --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -102,10 +102,13 @@ class DWARFContext : public DIContext { protected: std::unique_ptr DObj; + std::string DWPName; public: - DWARFContext(std::unique_ptr DObj) - : DIContext(CK_DWARF), DObj(std::move(DObj)) {} + DWARFContext(std::unique_ptr DObj, + std::string DWPName = "") + : DIContext(CK_DWARF), DObj(std::move(DObj)), + DWPName(std::move(DWPName)) {} DWARFContext(DWARFContext &) = delete; DWARFContext &operator=(DWARFContext &) = delete; @@ -245,7 +248,8 @@ public: static ErrorPolicy defaultErrorHandler(Error E); static std::unique_ptr create(const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr, - function_ref HandleError = defaultErrorHandler); + function_ref HandleError = defaultErrorHandler, + std::string DWPName = ""); static std::unique_ptr create(const StringMap> &Sections, diff --git a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h index d98d49b24bca..6480aef109c6 100644 --- a/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h +++ b/llvm/include/llvm/DebugInfo/Symbolize/Symbolize.h @@ -58,9 +58,11 @@ public: } Expected symbolizeCode(const std::string &ModuleName, - uint64_t ModuleOffset); + uint64_t ModuleOffset, + StringRef DWPName = ""); Expected symbolizeInlinedCode(const std::string &ModuleName, - uint64_t ModuleOffset); + uint64_t ModuleOffset, + StringRef DWPName = ""); Expected symbolizeData(const std::string &ModuleName, uint64_t ModuleOffset); void flush(); @@ -79,7 +81,7 @@ private: /// only reported once. Subsequent calls to get module info for a module that /// failed to load will return nullptr. Expected - getOrCreateModuleInfo(const std::string &ModuleName); + getOrCreateModuleInfo(const std::string &ModuleName, StringRef DWPName = ""); ObjectFile *lookUpDsymFile(const std::string &Path, const MachOObjectFile *ExeObj, diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp index 67f39ec1b1a4..aeb1dea2bca3 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -792,11 +792,13 @@ DWARFContext::getDWOContext(StringRef AbsolutePath) { return std::shared_ptr(std::move(S), Ctxt); } - SmallString<128> DWPName; Expected> Obj = [&] { if (!CheckedForDWP) { - (DObj->getFileName() + ".dwp").toVector(DWPName); - auto Obj = object::ObjectFile::createObjectFile(DWPName); + SmallString<128> DWPName; + auto Obj = object::ObjectFile::createObjectFile( + this->DWPName.empty() + ? (DObj->getFileName() + ".dwp").toStringRef(DWPName) + : StringRef(this->DWPName)); if (Obj) { Entry = &DWP; return Obj; @@ -1252,9 +1254,10 @@ public: std::unique_ptr DWARFContext::create(const object::ObjectFile &Obj, const LoadedObjectInfo *L, - function_ref HandleError) { + function_ref HandleError, + std::string DWPName) { auto DObj = llvm::make_unique(Obj, L, HandleError); - return llvm::make_unique(std::move(DObj)); + return llvm::make_unique(std::move(DObj), std::move(DWPName)); } std::unique_ptr @@ -1262,5 +1265,5 @@ DWARFContext::create(const StringMap> &Sections, uint8_t AddrSize, bool isLittleEndian) { auto DObj = llvm::make_unique(Sections, AddrSize, isLittleEndian); - return llvm::make_unique(std::move(DObj)); + return llvm::make_unique(std::move(DObj), ""); } diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp index 1d8b43216476..7aa55e755d2c 100644 --- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -53,10 +53,11 @@ namespace llvm { namespace symbolize { -Expected LLVMSymbolizer::symbolizeCode(const std::string &ModuleName, - uint64_t ModuleOffset) { +Expected +LLVMSymbolizer::symbolizeCode(const std::string &ModuleName, + uint64_t ModuleOffset, StringRef DWPName) { SymbolizableModule *Info; - if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName)) + if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName, DWPName)) Info = InfoOrErr.get(); else return InfoOrErr.takeError(); @@ -80,9 +81,9 @@ Expected LLVMSymbolizer::symbolizeCode(const std::string &ModuleName Expected LLVMSymbolizer::symbolizeInlinedCode(const std::string &ModuleName, - uint64_t ModuleOffset) { + uint64_t ModuleOffset, StringRef DWPName) { SymbolizableModule *Info; - if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName)) + if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName, DWPName)) Info = InfoOrErr.get(); else return InfoOrErr.takeError(); @@ -364,7 +365,8 @@ LLVMSymbolizer::getOrCreateObject(const std::string &Path, } Expected -LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName) { +LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName, + StringRef DWPName) { const auto &I = Modules.find(ModuleName); if (I != Modules.end()) { return I->second.get(); @@ -409,7 +411,8 @@ LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName) { } } if (!Context) - Context = DWARFContext::create(*Objects.second); + Context = DWARFContext::create(*Objects.second, nullptr, + DWARFContext::defaultErrorHandler, DWPName); assert(Context); auto InfoOrErr = SymbolizableObjectFile::create(Objects.first, std::move(Context)); diff --git a/llvm/test/DebugInfo/llvm-symbolizer.test b/llvm/test/DebugInfo/llvm-symbolizer.test index bcad37cf9a48..342c1a9e925c 100644 --- a/llvm/test/DebugInfo/llvm-symbolizer.test +++ b/llvm/test/DebugInfo/llvm-symbolizer.test @@ -50,6 +50,11 @@ RUN: echo "%p/Inputs/split-dwarf-test 0x4005c4" >> %t.input RUN: llvm-symbolizer --functions=linkage --inlining --demangle=false \ RUN: --default-arch=i386 < %t.input | FileCheck --check-prefix=SPLIT --check-prefix=NODWO %s +RUN: cp %p/Inputs/split-dwarf-dwp.o %T/split-dwarf-dwp-different-name.o +RUN: echo "%T/split-dwarf-dwp-different-name.o 0x4" > %t.input +RUN: llvm-symbolizer --functions=linkage --inlining --demangle=false \ +RUN: --default-arch=i386 --dwp=%p/Inputs/split-dwarf-dwp.o.dwp < %t.input | FileCheck --check-prefix=DWP %s + CHECK: main CHECK-NEXT: /tmp/dbginfo{{[/\\]}}dwarfdump-test.cc:16 @@ -151,10 +156,10 @@ CHECK-NEXT: split-dwarf-addr-object-relocation.cpp:3:3 CHECK-NEXT: f3 CHECK-NEXT: split-dwarf-addr-object-relocation.cpp:6:0 -CHECK: f2 -CHECK-NEXT: split-dwarf-dwp.cpp:3:3 -CHECK-NEXT: f3 -CHECK-NEXT: split-dwarf-dwp.cpp:6:0 +DWP: f2 +DWP-NEXT: split-dwarf-dwp.cpp:3:3 +DWP-NEXT: f3 +DWP-NEXT: split-dwarf-dwp.cpp:6:0 RUN: echo "unexisting-file 0x1234" > %t.input2 RUN: llvm-symbolizer < %t.input2 2>&1 | FileCheck %s --check-prefix=MISSING-FILE diff --git a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp index c9e0cc2b3b05..b51ec513f23b 100644 --- a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp +++ b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp @@ -69,6 +69,10 @@ ClBinaryName("obj", cl::init(""), cl::desc("Path to object file to be symbolized (if not provided, " "object file should be specified for each input line)")); +static cl::opt + ClDwpName("dwp", cl::init(""), + cl::desc("Path to DWP file to be use for any split CUs")); + static cl::list ClDsymHint("dsym-hint", cl::ZeroOrMore, cl::desc("Path to .dSYM bundles to search for debug info for the " @@ -191,11 +195,13 @@ int main(int argc, char **argv) { auto ResOrErr = Symbolizer.symbolizeData(ModuleName, ModuleOffset); Printer << (error(ResOrErr) ? DIGlobal() : ResOrErr.get()); } else if (ClPrintInlining) { - auto ResOrErr = Symbolizer.symbolizeInlinedCode(ModuleName, ModuleOffset); + auto ResOrErr = + Symbolizer.symbolizeInlinedCode(ModuleName, ModuleOffset, ClDwpName); Printer << (error(ResOrErr) ? DIInliningInfo() : ResOrErr.get()); } else { - auto ResOrErr = Symbolizer.symbolizeCode(ModuleName, ModuleOffset); + auto ResOrErr = + Symbolizer.symbolizeCode(ModuleName, ModuleOffset, ClDwpName); Printer << (error(ResOrErr) ? DILineInfo() : ResOrErr.get()); } outs() << "\n";