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
This commit is contained in:
David Blaikie 2017-07-30 01:34:08 +00:00
parent 67b0e589d0
commit e5adb68e04
6 changed files with 48 additions and 25 deletions

View File

@ -102,10 +102,13 @@ class DWARFContext : public DIContext {
protected:
std::unique_ptr<const DWARFObject> DObj;
std::string DWPName;
public:
DWARFContext(std::unique_ptr<const DWARFObject> DObj)
: DIContext(CK_DWARF), DObj(std::move(DObj)) {}
DWARFContext(std::unique_ptr<const DWARFObject> 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<DWARFContext>
create(const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr,
function_ref<ErrorPolicy(Error)> HandleError = defaultErrorHandler);
function_ref<ErrorPolicy(Error)> HandleError = defaultErrorHandler,
std::string DWPName = "");
static std::unique_ptr<DWARFContext>
create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,

View File

@ -58,9 +58,11 @@ public:
}
Expected<DILineInfo> symbolizeCode(const std::string &ModuleName,
uint64_t ModuleOffset);
uint64_t ModuleOffset,
StringRef DWPName = "");
Expected<DIInliningInfo> symbolizeInlinedCode(const std::string &ModuleName,
uint64_t ModuleOffset);
uint64_t ModuleOffset,
StringRef DWPName = "");
Expected<DIGlobal> 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<SymbolizableModule *>
getOrCreateModuleInfo(const std::string &ModuleName);
getOrCreateModuleInfo(const std::string &ModuleName, StringRef DWPName = "");
ObjectFile *lookUpDsymFile(const std::string &Path,
const MachOObjectFile *ExeObj,

View File

@ -792,11 +792,13 @@ DWARFContext::getDWOContext(StringRef AbsolutePath) {
return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
}
SmallString<128> DWPName;
Expected<OwningBinary<ObjectFile>> 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>
DWARFContext::create(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
function_ref<ErrorPolicy(Error)> HandleError) {
function_ref<ErrorPolicy(Error)> HandleError,
std::string DWPName) {
auto DObj = llvm::make_unique<DWARFObjInMemory>(Obj, L, HandleError);
return llvm::make_unique<DWARFContext>(std::move(DObj));
return llvm::make_unique<DWARFContext>(std::move(DObj), std::move(DWPName));
}
std::unique_ptr<DWARFContext>
@ -1262,5 +1265,5 @@ DWARFContext::create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
uint8_t AddrSize, bool isLittleEndian) {
auto DObj =
llvm::make_unique<DWARFObjInMemory>(Sections, AddrSize, isLittleEndian);
return llvm::make_unique<DWARFContext>(std::move(DObj));
return llvm::make_unique<DWARFContext>(std::move(DObj), "");
}

View File

@ -53,10 +53,11 @@
namespace llvm {
namespace symbolize {
Expected<DILineInfo> LLVMSymbolizer::symbolizeCode(const std::string &ModuleName,
uint64_t ModuleOffset) {
Expected<DILineInfo>
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<DILineInfo> LLVMSymbolizer::symbolizeCode(const std::string &ModuleName
Expected<DIInliningInfo>
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<SymbolizableModule *>
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));

View File

@ -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

View File

@ -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<std::string>
ClDwpName("dwp", cl::init(""),
cl::desc("Path to DWP file to be use for any split CUs"));
static cl::list<std::string>
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";