Index: docs/CommandGuide/llvm-symbolizer.rst =================================================================== --- docs/CommandGuide/llvm-symbolizer.rst +++ docs/CommandGuide/llvm-symbolizer.rst @@ -56,6 +56,14 @@ foo(int) /tmp/a.cc:12 + $cat addr.txt + 0x40054d + $llvm-symbolizer -inlining -print-address -pretty-print -obj=addr.exe < addr.txt + 0x40054d: inc at /tmp/x.c:3:3 + (inlined by) main at /tmp/x.c:9:0 + $llvm-symbolizer -inlining -pretty-print -obj=addr.exe < addr.txt + inc at /tmp/x.c:3:3 + (inlined by) main at /tmp/x.c:9:0 OPTIONS ------- @@ -101,6 +109,10 @@ .. option:: -print-address Print address before the source code location. Defaults to false. +.. option:: -pretty-print + Print human readable output. If -inlining is specified, enclosing scope is + prefixed by (inlined by). Refer examples listed. + EXIT STATUS ----------- Index: test/tools/llvm-symbolizer/sym.test =================================================================== --- test/tools/llvm-symbolizer/sym.test +++ test/tools/llvm-symbolizer/sym.test @@ -12,8 +12,12 @@ #Build as : clang -g -O2 addr.c RUN: llvm-symbolizer -inlining -print-address -obj=%p/Inputs/addr.exe < %p/Inputs/addr.inp | FileCheck %s +RUN: llvm-symbolizer -inlining -print-address -pretty-print -obj=%p/Inputs/addr.exe < %p/Inputs/addr.inp | FileCheck --check-prefix="PRETTY" %s -#CHECK: 0x40054d +#CHECK: {{[0x]+}}40054d #CHECK: main #CHECK: {{[/\]+}}tmp{{[/\]+}}x.c:9:0 +# +#PRETTY: {{[0x]+}}40054d: inc at {{[/\]+}}tmp{{[/\]+}}x.c:3:3 +#PRETTY: (inlined by) main at {{[/\]+}}tmp{{[/\]+}}x.c:9:0 Index: tools/llvm-symbolizer/LLVMSymbolize.h =================================================================== --- tools/llvm-symbolizer/LLVMSymbolize.h +++ tools/llvm-symbolizer/LLVMSymbolize.h @@ -41,14 +41,16 @@ bool Demangle : 1; bool RelativeAddresses : 1; std::string DefaultArch; + bool PrintPretty : 1; std::vector DsymHints; Options(FunctionNameKind PrintFunctions = FunctionNameKind::LinkageName, bool UseSymbolTable = true, bool PrintInlining = true, bool Demangle = true, bool RelativeAddresses = false, - std::string DefaultArch = "") + std::string DefaultArch = "", bool PrintPretty = false) : PrintFunctions(PrintFunctions), UseSymbolTable(UseSymbolTable), PrintInlining(PrintInlining), Demangle(Demangle), - RelativeAddresses(RelativeAddresses), DefaultArch(DefaultArch) {} + RelativeAddresses(RelativeAddresses), DefaultArch(DefaultArch), + PrintPretty(PrintPretty) {} }; LLVMSymbolizer(const Options &Opts = Options()) : Opts(Opts) {} Index: tools/llvm-symbolizer/LLVMSymbolize.cpp =================================================================== --- tools/llvm-symbolizer/LLVMSymbolize.cpp +++ tools/llvm-symbolizer/LLVMSymbolize.cpp @@ -149,7 +149,7 @@ // of the function's code, not the descriptor. uint64_t OpdOffset = SymbolAddress - OpdAddress; uint32_t OpdOffset32 = OpdOffset; - if (OpdOffset == OpdOffset32 && + if (OpdOffset == OpdOffset32 && OpdExtractor->isValidOffsetForAddress(OpdOffset32)) SymbolAddress = OpdExtractor->getAddress(&OpdOffset32); } @@ -278,6 +278,8 @@ for (uint32_t i = 0; i < FramesNum; i++) { DILineInfo LineInfo = InlinedContext.getFrame(i); Result += printDILineInfo(LineInfo, Info); + if (Opts.PrintPretty && i < FramesNum - 1) + Result += " (inlined by) "; } return Result; } @@ -432,7 +434,7 @@ if (!MachDbgObj) continue; if (darwinDsymMatchesBinary(MachDbgObj, MachExeObj)) { addOwningBinary(std::move(B)); - return DbgObj; + return DbgObj; } } } @@ -560,7 +562,11 @@ FunctionName = kBadString; else if (Opts.Demangle) FunctionName = DemangleName(FunctionName, ModInfo); - Result << FunctionName << "\n"; + Result << FunctionName; + if (Opts.PrintPretty) + Result << " at "; + else + Result << "\n"; } std::string Filename = LineInfo.FileName; if (Filename == kDILineInfoBadString) Index: tools/llvm-symbolizer/llvm-symbolizer.cpp =================================================================== --- tools/llvm-symbolizer/llvm-symbolizer.cpp +++ tools/llvm-symbolizer/llvm-symbolizer.cpp @@ -77,6 +77,9 @@ ClPrintAddress("print-address", cl::init(false), cl::desc("Show address before line information")); +static cl::opt ClPrettyPrint("pretty-print", cl::init(false), + cl::desc("Show human readable information")); + static bool parseCommand(bool &IsData, std::string &ModuleName, uint64_t &ModuleOffset) { const char *kDataCmd = "DATA "; @@ -135,9 +138,9 @@ llvm::sys::InitializeCOMRAII COM(llvm::sys::COMThreadingMode::MultiThreaded); cl::ParseCommandLineOptions(argc, argv, "llvm-symbolizer\n"); - LLVMSymbolizer::Options Opts(ClPrintFunctions, ClUseSymbolTable, - ClPrintInlining, ClDemangle, - ClUseRelativeAddress, ClDefaultArch); + LLVMSymbolizer::Options Opts( + ClPrintFunctions, ClUseSymbolTable, ClPrintInlining, ClDemangle, + ClUseRelativeAddress, ClDefaultArch, ClPrettyPrint); for (const auto &hint : ClDsymHint) { if (sys::path::extension(hint) == ".dSYM") { Opts.DsymHints.push_back(hint); @@ -158,7 +161,10 @@ if (ClPrintAddress) { outs() << "0x"; outs().write_hex(ModuleOffset); - outs() << "\n"; + if (!ClPrettyPrint) + outs() << "\n"; + else + outs() << ": "; } outs() << Result << "\n"; outs().flush();