diff options
Diffstat (limited to 'llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp')
-rw-r--r-- | llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp | 63 |
1 files changed, 37 insertions, 26 deletions
diff --git a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp index 1b86134dda51..3e342a4db9ce 100644 --- a/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp +++ b/llvm/tools/llvm-symbolizer/llvm-symbolizer.cpp @@ -36,6 +36,7 @@ #include "llvm/Support/InitLLVM.h" #include "llvm/Support/Path.h" #include "llvm/Support/StringSaver.h" +#include "llvm/Support/WithColor.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> #include <cstdio> @@ -83,6 +84,16 @@ public: }; } // namespace +static std::string ToolName; + +static void printError(const ErrorInfoBase &EI, StringRef Path) { + WithColor::error(errs(), ToolName); + if (!EI.isA<FileError>()) + errs() << "'" << Path << "': "; + EI.log(errs()); + errs() << '\n'; +} + template <typename T> static void print(const Request &Request, Expected<T> &ResOrErr, DIPrinter &Printer) { @@ -96,8 +107,7 @@ static void print(const Request &Request, Expected<T> &ResOrErr, bool PrintEmpty = true; handleAllErrors(std::move(ResOrErr.takeError()), [&](const ErrorInfoBase &EI) { - PrintEmpty = Printer.printError( - Request, EI, "LLVMSymbolizer: error reading file: "); + PrintEmpty = Printer.printError(Request, EI); }); if (PrintEmpty) @@ -125,15 +135,6 @@ static void enableDebuginfod(LLVMSymbolizer &Symbolizer, HTTPClient::initialize(); } -static object::BuildID parseBuildID(StringRef Str) { - std::string Bytes; - if (!tryGetFromHex(Str, Bytes)) - return {}; - ArrayRef<uint8_t> BuildID(reinterpret_cast<const uint8_t *>(Bytes.data()), - Bytes.size()); - return object::BuildID(BuildID.begin(), BuildID.end()); -} - static bool parseCommand(StringRef BinaryName, bool IsAddr2Line, StringRef InputString, Command &Cmd, std::string &ModuleName, object::BuildID &BuildID, @@ -218,17 +219,18 @@ void executeCommand(StringRef ModuleName, const T &ModuleSpec, Command Cmd, uint64_t AdjustedOffset = Offset - AdjustVMA; object::SectionedAddress Address = {AdjustedOffset, object::SectionedAddress::UndefSection}; + Request SymRequest = {ModuleName, Offset}; if (Cmd == Command::Data) { Expected<DIGlobal> ResOrErr = Symbolizer.symbolizeData(ModuleSpec, Address); - print({ModuleName, Offset}, ResOrErr, Printer); + print(SymRequest, ResOrErr, Printer); } else if (Cmd == Command::Frame) { Expected<std::vector<DILocal>> ResOrErr = Symbolizer.symbolizeFrame(ModuleSpec, Address); - print({ModuleName, Offset}, ResOrErr, Printer); + print(SymRequest, ResOrErr, Printer); } else if (ShouldInline) { Expected<DIInliningInfo> ResOrErr = Symbolizer.symbolizeInlinedCode(ModuleSpec, Address); - print({ModuleName, Offset}, ResOrErr, Printer); + print(SymRequest, ResOrErr, Printer); } else if (Style == OutputStyle::GNU) { // With PrintFunctions == FunctionNameKind::LinkageName (default) // and UseSymbolTable == true (also default), Symbolizer.symbolizeCode() @@ -243,11 +245,11 @@ void executeCommand(StringRef ModuleName, const T &ModuleSpec, Command Cmd, ? Expected<DILineInfo>(ResOrErr.takeError()) : ((ResOrErr->getNumberOfFrames() == 0) ? DILineInfo() : ResOrErr->getFrame(0)); - print({ModuleName, Offset}, Res0OrErr, Printer); + print(SymRequest, Res0OrErr, Printer); } else { Expected<DILineInfo> ResOrErr = Symbolizer.symbolizeCode(ModuleSpec, Address); - print({ModuleName, Offset}, ResOrErr, Printer); + print(SymRequest, ResOrErr, Printer); } Symbolizer.pruneCache(); } @@ -386,7 +388,8 @@ int main(int argc, char **argv) { InitLLVM X(argc, argv); sys::InitializeCOMRAII COM(sys::COMThreadingMode::MultiThreaded); - bool IsAddr2Line = sys::path::stem(argv[0]).contains("addr2line"); + ToolName = argv[0]; + bool IsAddr2Line = sys::path::stem(ToolName).contains("addr2line"); BumpPtrAllocator A; StringSaver Saver(A); SymbolizerOptTable Tbl; @@ -443,13 +446,7 @@ int main(int argc, char **argv) { LLVMSymbolizer Symbolizer(Opts); - // A debuginfod lookup could succeed if a HTTP client is available and at - // least one backing URL is configured. - bool ShouldUseDebuginfodByDefault = - HTTPClient::isAvailable() && - !ExitOnErr(getDefaultDebuginfodUrls()).empty(); - if (Args.hasFlag(OPT_debuginfod, OPT_no_debuginfod, - ShouldUseDebuginfodByDefault)) + if (Args.hasFlag(OPT_debuginfod, OPT_no_debuginfod, canUseDebuginfod())) enableDebuginfod(Symbolizer, Args); if (Args.hasArg(OPT_filter_markup)) { @@ -475,11 +472,25 @@ int main(int argc, char **argv) { std::unique_ptr<DIPrinter> Printer; if (Style == OutputStyle::GNU) - Printer = std::make_unique<GNUPrinter>(outs(), errs(), Config); + Printer = std::make_unique<GNUPrinter>(outs(), printError, Config); else if (Style == OutputStyle::JSON) Printer = std::make_unique<JSONPrinter>(outs(), Config); else - Printer = std::make_unique<LLVMPrinter>(outs(), errs(), Config); + Printer = std::make_unique<LLVMPrinter>(outs(), printError, Config); + + // When an input file is specified, exit immediately if the file cannot be + // read. If getOrCreateModuleInfo succeeds, symbolizeInput will reuse the + // cached file handle. + if (auto *Arg = Args.getLastArg(OPT_obj_EQ); Arg) { + auto Status = Symbolizer.getOrCreateModuleInfo(Arg->getValue()); + if (!Status) { + Request SymRequest = {Arg->getValue(), 0}; + handleAllErrors(Status.takeError(), [&](const ErrorInfoBase &EI) { + Printer->printError(SymRequest, EI); + }); + return EXIT_FAILURE; + } + } std::vector<std::string> InputAddresses = Args.getAllArgValues(OPT_INPUT); if (InputAddresses.empty()) { |