[llvm] r252021 - [LLVMSymbolize] Properly propagate object parsing errors from the library.
Alexey Samsonov via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 3 16:30:24 PST 2015
Author: samsonov
Date: Tue Nov 3 18:30:24 2015
New Revision: 252021
URL: http://llvm.org/viewvc/llvm-project?rev=252021&view=rev
Log:
[LLVMSymbolize] Properly propagate object parsing errors from the library.
Modified:
llvm/trunk/include/llvm/DebugInfo/Symbolize/Symbolize.h
llvm/trunk/lib/DebugInfo/Symbolize/Symbolize.cpp
llvm/trunk/tools/llvm-symbolizer/llvm-symbolizer.cpp
Modified: llvm/trunk/include/llvm/DebugInfo/Symbolize/Symbolize.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Symbolize/Symbolize.h?rev=252021&r1=252020&r2=252021&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/Symbolize/Symbolize.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/Symbolize/Symbolize.h Tue Nov 3 18:30:24 2015
@@ -18,6 +18,7 @@
#include "llvm/DebugInfo/Symbolize/SymbolizableModule.h"
#include "llvm/Object/MachOUniversal.h"
#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/MemoryBuffer.h"
#include <map>
#include <memory>
@@ -51,11 +52,12 @@ public:
flush();
}
- DILineInfo symbolizeCode(const std::string &ModuleName,
- uint64_t ModuleOffset);
- DIInliningInfo symbolizeInlinedCode(const std::string &ModuleName,
- uint64_t ModuleOffset);
- DIGlobal symbolizeData(const std::string &ModuleName, uint64_t ModuleOffset);
+ ErrorOr<DILineInfo> symbolizeCode(const std::string &ModuleName,
+ uint64_t ModuleOffset);
+ ErrorOr<DIInliningInfo> symbolizeInlinedCode(const std::string &ModuleName,
+ uint64_t ModuleOffset);
+ ErrorOr<DIGlobal> symbolizeData(const std::string &ModuleName,
+ uint64_t ModuleOffset);
void flush();
static std::string DemangleName(const std::string &Name,
const SymbolizableModule *ModInfo);
@@ -63,17 +65,19 @@ public:
private:
typedef std::pair<ObjectFile*, ObjectFile*> ObjectPair;
- SymbolizableModule *getOrCreateModuleInfo(const std::string &ModuleName);
+ ErrorOr<SymbolizableModule *>
+ getOrCreateModuleInfo(const std::string &ModuleName);
ObjectFile *lookUpDsymFile(const std::string &Path,
const MachOObjectFile *ExeObj,
const std::string &ArchName);
/// \brief Returns pair of pointers to object and debug object.
- ObjectPair getOrCreateObjects(const std::string &Path,
- const std::string &ArchName);
+ ErrorOr<ObjectPair> getOrCreateObjects(const std::string &Path,
+ const std::string &ArchName);
/// \brief Returns a parsed object file for a given architecture in a
/// universal binary (or the binary itself if it is an object file).
- ObjectFile *getObjectFileFromBinary(Binary *Bin, const std::string &ArchName);
+ ErrorOr<ObjectFile *> getObjectFileFromBinary(Binary *Bin,
+ const std::string &ArchName);
// Owns all the parsed binaries and object files.
SmallVector<std::unique_ptr<Binary>, 4> ParsedBinariesAndObjects;
@@ -86,10 +90,10 @@ private:
MemoryBuffers.push_back(std::move(MemBuf));
}
- std::map<std::string, std::unique_ptr<SymbolizableModule>> Modules;
- std::map<std::pair<MachOUniversalBinary *, std::string>, ObjectFile *>
- ObjectFileForArch;
- std::map<std::pair<std::string, std::string>, ObjectPair>
+ std::map<std::string, ErrorOr<std::unique_ptr<SymbolizableModule>>> Modules;
+ std::map<std::pair<MachOUniversalBinary *, std::string>,
+ ErrorOr<ObjectFile *>> ObjectFileForArch;
+ std::map<std::pair<std::string, std::string>, ErrorOr<ObjectPair>>
ObjectPairForPathArch;
Options Opts;
Modified: llvm/trunk/lib/DebugInfo/Symbolize/Symbolize.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/Symbolize/Symbolize.cpp?rev=252021&r1=252020&r2=252021&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/Symbolize/Symbolize.cpp (original)
+++ llvm/trunk/lib/DebugInfo/Symbolize/Symbolize.cpp Tue Nov 3 18:30:24 2015
@@ -46,19 +46,12 @@
namespace llvm {
namespace symbolize {
-// FIXME: Move this to llvm-symbolizer tool.
-static bool error(std::error_code ec) {
- if (!ec)
- return false;
- errs() << "LLVMSymbolizer: error reading file: " << ec.message() << ".\n";
- return true;
-}
-
-DILineInfo LLVMSymbolizer::symbolizeCode(const std::string &ModuleName,
- uint64_t ModuleOffset) {
- SymbolizableModule *Info = getOrCreateModuleInfo(ModuleName);
- if (!Info)
- return DILineInfo();
+ErrorOr<DILineInfo> LLVMSymbolizer::symbolizeCode(const std::string &ModuleName,
+ uint64_t ModuleOffset) {
+ auto InfoOrErr = getOrCreateModuleInfo(ModuleName);
+ if (auto EC = InfoOrErr.getError())
+ return EC;
+ SymbolizableModule *Info = InfoOrErr.get();
// If the user is giving us relative addresses, add the preferred base of the
// object to the offset before we do the query. It's what DIContext expects.
@@ -72,12 +65,13 @@ DILineInfo LLVMSymbolizer::symbolizeCode
return LineInfo;
}
-DIInliningInfo
+ErrorOr<DIInliningInfo>
LLVMSymbolizer::symbolizeInlinedCode(const std::string &ModuleName,
uint64_t ModuleOffset) {
- SymbolizableModule *Info = getOrCreateModuleInfo(ModuleName);
- if (!Info)
- return DIInliningInfo();
+ auto InfoOrErr = getOrCreateModuleInfo(ModuleName);
+ if (auto EC = InfoOrErr.getError())
+ return EC;
+ SymbolizableModule *Info = InfoOrErr.get();
// If the user is giving us relative addresses, add the preferred base of the
// object to the offset before we do the query. It's what DIContext expects.
@@ -95,13 +89,12 @@ LLVMSymbolizer::symbolizeInlinedCode(con
return InlinedContext;
}
-DIGlobal LLVMSymbolizer::symbolizeData(const std::string &ModuleName,
- uint64_t ModuleOffset) {
- if (!Opts.UseSymbolTable)
- return DIGlobal();
- SymbolizableModule *Info = getOrCreateModuleInfo(ModuleName);
- if (!Info)
- return DIGlobal();
+ErrorOr<DIGlobal> LLVMSymbolizer::symbolizeData(const std::string &ModuleName,
+ uint64_t ModuleOffset) {
+ auto InfoOrErr = getOrCreateModuleInfo(ModuleName);
+ if (auto EC = InfoOrErr.getError())
+ return EC;
+ SymbolizableModule *Info = InfoOrErr.get();
// If the user is giving us relative addresses, add the preferred base of
// the object to the offset before we do the query. It's what DIContext
@@ -232,72 +225,87 @@ ObjectFile *LLVMSymbolizer::lookUpDsymFi
}
for (const auto &path : DsymPaths) {
ErrorOr<OwningBinary<Binary>> BinaryOrErr = createBinary(path);
- std::error_code EC = BinaryOrErr.getError();
- if (EC != errc::no_such_file_or_directory && !error(EC)) {
- OwningBinary<Binary> B = std::move(BinaryOrErr.get());
- ObjectFile *DbgObj =
- getObjectFileFromBinary(B.getBinary(), ArchName);
- const MachOObjectFile *MachDbgObj =
- dyn_cast<const MachOObjectFile>(DbgObj);
- if (!MachDbgObj) continue;
- if (darwinDsymMatchesBinary(MachDbgObj, MachExeObj)) {
- addOwningBinary(std::move(B));
- return DbgObj;
- }
+ if (!BinaryOrErr)
+ continue;
+ OwningBinary<Binary> &B = BinaryOrErr.get();
+ auto DbgObjOrErr = getObjectFileFromBinary(B.getBinary(), ArchName);
+ if (!DbgObjOrErr)
+ continue;
+ ObjectFile *DbgObj = DbgObjOrErr.get();
+ const MachOObjectFile *MachDbgObj =
+ dyn_cast<const MachOObjectFile>(DbgObj);
+ if (!MachDbgObj)
+ continue;
+ if (darwinDsymMatchesBinary(MachDbgObj, MachExeObj)) {
+ addOwningBinary(std::move(B));
+ return DbgObj;
}
}
return nullptr;
}
-LLVMSymbolizer::ObjectPair
+ErrorOr<LLVMSymbolizer::ObjectPair>
LLVMSymbolizer::getOrCreateObjects(const std::string &Path,
const std::string &ArchName) {
const auto &I = ObjectPairForPathArch.find(std::make_pair(Path, ArchName));
if (I != ObjectPairForPathArch.end())
return I->second;
- ObjectFile *Obj = nullptr;
- ObjectFile *DbgObj = nullptr;
+
ErrorOr<OwningBinary<Binary>> BinaryOrErr = createBinary(Path);
- if (!error(BinaryOrErr.getError())) {
- OwningBinary<Binary> &B = BinaryOrErr.get();
- Obj = getObjectFileFromBinary(B.getBinary(), ArchName);
- if (!Obj) {
- ObjectPair Res = std::make_pair(nullptr, nullptr);
- ObjectPairForPathArch[std::make_pair(Path, ArchName)] = Res;
- return Res;
- }
- addOwningBinary(std::move(B));
- if (auto MachObj = dyn_cast<const MachOObjectFile>(Obj))
- DbgObj = lookUpDsymFile(Path, MachObj, ArchName);
- // Try to locate the debug binary using .gnu_debuglink section.
- if (!DbgObj) {
- std::string DebuglinkName;
- uint32_t CRCHash;
- std::string DebugBinaryPath;
- if (getGNUDebuglinkContents(Obj, DebuglinkName, CRCHash) &&
- findDebugBinary(Path, DebuglinkName, CRCHash, DebugBinaryPath)) {
- BinaryOrErr = createBinary(DebugBinaryPath);
- if (!error(BinaryOrErr.getError())) {
- OwningBinary<Binary> B = std::move(BinaryOrErr.get());
- DbgObj = getObjectFileFromBinary(B.getBinary(), ArchName);
- addOwningBinary(std::move(B));
+ if (auto EC = BinaryOrErr.getError()) {
+ ObjectPairForPathArch.insert(
+ std::make_pair(std::make_pair(Path, ArchName), EC));
+ return EC;
+ }
+ OwningBinary<Binary> &B = BinaryOrErr.get();
+
+ auto ObjOrErr = getObjectFileFromBinary(B.getBinary(), ArchName);
+ if (auto EC = ObjOrErr.getError()) {
+ ObjectPairForPathArch.insert(
+ std::make_pair(std::make_pair(Path, ArchName), EC));
+ return EC;
+ }
+ addOwningBinary(std::move(B));
+
+ ObjectFile *Obj = ObjOrErr.get();
+ assert(Obj != nullptr);
+ ObjectFile *DbgObj = nullptr;
+
+ if (auto MachObj = dyn_cast<const MachOObjectFile>(Obj))
+ DbgObj = lookUpDsymFile(Path, MachObj, ArchName);
+ // Try to locate the debug binary using .gnu_debuglink section.
+ if (!DbgObj) {
+ std::string DebuglinkName;
+ uint32_t CRCHash;
+ std::string DebugBinaryPath;
+ if (getGNUDebuglinkContents(Obj, DebuglinkName, CRCHash) &&
+ findDebugBinary(Path, DebuglinkName, CRCHash, DebugBinaryPath)) {
+ ErrorOr<OwningBinary<Binary>> DebugBinaryOrErr =
+ createBinary(DebugBinaryPath);
+ if (DebugBinaryOrErr) {
+ OwningBinary<Binary> &DB = DebugBinaryOrErr.get();
+ auto DbgObjOrErr = getObjectFileFromBinary(DB.getBinary(), ArchName);
+ if (DbgObjOrErr) {
+ DbgObj = DbgObjOrErr.get();
+ assert(DbgObj != nullptr);
+ addOwningBinary(std::move(DB));
}
}
}
}
+
if (!DbgObj)
DbgObj = Obj;
ObjectPair Res = std::make_pair(Obj, DbgObj);
- ObjectPairForPathArch[std::make_pair(Path, ArchName)] = Res;
+ ObjectPairForPathArch.insert(
+ std::make_pair(std::make_pair(Path, ArchName), Res));
return Res;
}
-ObjectFile *
+ErrorOr<ObjectFile *>
LLVMSymbolizer::getObjectFileFromBinary(Binary *Bin,
const std::string &ArchName) {
- if (!Bin)
- return nullptr;
- ObjectFile *Res = nullptr;
+ assert(Bin != nullptr);
if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(Bin)) {
const auto &I = ObjectFileForArch.find(
std::make_pair(UB, ArchName));
@@ -305,22 +313,31 @@ LLVMSymbolizer::getObjectFileFromBinary(
return I->second;
ErrorOr<std::unique_ptr<ObjectFile>> ParsedObj =
UB->getObjectForArch(ArchName);
- if (ParsedObj) {
- Res = ParsedObj.get().get();
- ParsedBinariesAndObjects.push_back(std::move(ParsedObj.get()));
+ if (auto EC = ParsedObj.getError()) {
+ ObjectFileForArch.insert(
+ std::make_pair(std::make_pair(UB, ArchName), EC));
+ return EC;
}
- ObjectFileForArch[std::make_pair(UB, ArchName)] = Res;
- } else if (Bin->isObject()) {
- Res = cast<ObjectFile>(Bin);
+ ObjectFile *Res = ParsedObj.get().get();
+ ParsedBinariesAndObjects.push_back(std::move(ParsedObj.get()));
+ ObjectFileForArch.insert(std::make_pair(std::make_pair(UB, ArchName), Res));
+ return Res;
}
- return Res;
+ if (Bin->isObject()) {
+ return cast<ObjectFile>(Bin);
+ }
+ return object_error::arch_not_found;
}
-SymbolizableModule *
+ErrorOr<SymbolizableModule *>
LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName) {
const auto &I = Modules.find(ModuleName);
- if (I != Modules.end())
- return I->second.get();
+ if (I != Modules.end()) {
+ auto &InfoOrErr = I->second;
+ if (auto EC = InfoOrErr.getError())
+ return EC;
+ return InfoOrErr->get();
+ }
std::string BinaryName = ModuleName;
std::string ArchName = Opts.DefaultArch;
size_t ColonPos = ModuleName.find_last_of(':');
@@ -332,13 +349,14 @@ LLVMSymbolizer::getOrCreateModuleInfo(co
ArchName = ArchStr;
}
}
- ObjectPair Objects = getOrCreateObjects(BinaryName, ArchName);
-
- if (!Objects.first) {
+ auto ObjectsOrErr = getOrCreateObjects(BinaryName, ArchName);
+ if (auto EC = ObjectsOrErr.getError()) {
// Failed to find valid object file.
- Modules.insert(std::make_pair(ModuleName, nullptr));
- return nullptr;
+ Modules.insert(std::make_pair(ModuleName, EC));
+ return EC;
}
+ ObjectPair Objects = ObjectsOrErr.get();
+
std::unique_ptr<DIContext> Context;
if (auto CoffObject = dyn_cast<COFFObjectFile>(Objects.first)) {
// If this is a COFF object, assume it contains PDB debug information. If
@@ -353,15 +371,14 @@ LLVMSymbolizer::getOrCreateModuleInfo(co
if (!Context)
Context.reset(new DWARFContextInMemory(*Objects.second));
assert(Context);
- auto ErrOrInfo =
+ auto InfoOrErr =
SymbolizableObjectFile::create(Objects.first, std::move(Context));
- if (error(ErrOrInfo.getError())) {
- Modules.insert(std::make_pair(ModuleName, nullptr));
- return nullptr;
- }
- SymbolizableModule *Res = ErrOrInfo.get().get();
- Modules.insert(std::make_pair(ModuleName, std::move(ErrOrInfo.get())));
- return Res;
+ auto InsertResult =
+ Modules.insert(std::make_pair(ModuleName, std::move(InfoOrErr)));
+ assert(InsertResult.second);
+ if (auto EC = InsertResult.first->second.getError())
+ return EC;
+ return InsertResult.first->second->get();
}
// Undo these various manglings for Win32 extern "C" functions:
Modified: llvm/trunk/tools/llvm-symbolizer/llvm-symbolizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-symbolizer/llvm-symbolizer.cpp?rev=252021&r1=252020&r2=252021&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-symbolizer/llvm-symbolizer.cpp (original)
+++ llvm/trunk/tools/llvm-symbolizer/llvm-symbolizer.cpp Tue Nov 3 18:30:24 2015
@@ -78,6 +78,13 @@ static cl::opt<bool>
ClPrintAddress("print-address", cl::init(false),
cl::desc("Show address before line information"));
+static bool error(std::error_code ec) {
+ if (!ec)
+ return false;
+ errs() << "LLVMSymbolizer: error reading file: " << ec.message() << ".\n";
+ return true;
+}
+
static bool parseCommand(bool &IsData, std::string &ModuleName,
uint64_t &ModuleOffset) {
const char *kDataCmd = "DATA ";
@@ -158,11 +165,15 @@ int main(int argc, char **argv) {
outs() << "\n";
}
if (IsData) {
- Printer << Symbolizer.symbolizeData(ModuleName, ModuleOffset);
+ auto ResOrErr = Symbolizer.symbolizeData(ModuleName, ModuleOffset);
+ Printer << (error(ResOrErr.getError()) ? DIGlobal() : ResOrErr.get());
} else if (ClPrintInlining) {
- Printer << Symbolizer.symbolizeInlinedCode(ModuleName, ModuleOffset);
+ auto ResOrErr = Symbolizer.symbolizeInlinedCode(ModuleName, ModuleOffset);
+ Printer << (error(ResOrErr.getError()) ? DIInliningInfo()
+ : ResOrErr.get());
} else {
- Printer << Symbolizer.symbolizeCode(ModuleName, ModuleOffset);
+ auto ResOrErr = Symbolizer.symbolizeCode(ModuleName, ModuleOffset);
+ Printer << (error(ResOrErr.getError()) ? DILineInfo() : ResOrErr.get());
}
outs() << "\n";
outs().flush();
More information about the llvm-commits
mailing list