From 5776ed04cef98e3b0c551dfb05e0e717b6894dc4 Mon Sep 17 00:00:00 2001 From: Hemant Kulkarni Date: Wed, 11 Nov 2015 17:47:54 +0000 Subject: [PATCH] [Symbolizer]: Add -pretty-print option Differential Revision: http://reviews.llvm.org/D13671 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@252760 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/CommandGuide/llvm-symbolizer.rst | 12 +++++++++++ include/llvm/DebugInfo/Symbolize/DIPrinter.h | 8 ++++++-- lib/DebugInfo/Symbolize/DIPrinter.cpp | 20 +++++++++++++------ test/tools/llvm-symbolizer/Inputs/addr.exe | Bin 9749 -> 10154 bytes test/tools/llvm-symbolizer/sym.test | 17 +++++++++++++--- tools/llvm-symbolizer/llvm-symbolizer.cpp | 11 ++++++++-- 6 files changed, 55 insertions(+), 13 deletions(-) diff --git a/docs/CommandGuide/llvm-symbolizer.rst b/docs/CommandGuide/llvm-symbolizer.rst index 9d6571d5c4c..dfbf4919abe 100644 --- a/docs/CommandGuide/llvm-symbolizer.rst +++ b/docs/CommandGuide/llvm-symbolizer.rst @@ -56,6 +56,14 @@ EXAMPLE 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 @@ OPTIONS .. 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 to listed examples. + EXIT STATUS ----------- diff --git a/include/llvm/DebugInfo/Symbolize/DIPrinter.h b/include/llvm/DebugInfo/Symbolize/DIPrinter.h index 6e192253d5d..0703fb14da6 100644 --- a/include/llvm/DebugInfo/Symbolize/DIPrinter.h +++ b/include/llvm/DebugInfo/Symbolize/DIPrinter.h @@ -27,10 +27,14 @@ namespace symbolize { class DIPrinter { raw_ostream &OS; bool PrintFunctionNames; + bool PrintPretty; + void printName(const DILineInfo &Info, bool Inlined); public: - DIPrinter(raw_ostream &OS, bool PrintFunctionNames = true) - : OS(OS), PrintFunctionNames(PrintFunctionNames) {} + DIPrinter(raw_ostream &OS, bool PrintFunctionNames = true, + bool PrintPretty = false) + : OS(OS), PrintFunctionNames(PrintFunctionNames), + PrintPretty(PrintPretty) {} DIPrinter &operator<<(const DILineInfo &Info); DIPrinter &operator<<(const DIInliningInfo &Info); diff --git a/lib/DebugInfo/Symbolize/DIPrinter.cpp b/lib/DebugInfo/Symbolize/DIPrinter.cpp index ad5f693d77e..c6bfbc07dcf 100644 --- a/lib/DebugInfo/Symbolize/DIPrinter.cpp +++ b/lib/DebugInfo/Symbolize/DIPrinter.cpp @@ -24,27 +24,35 @@ namespace symbolize { static const char kDILineInfoBadString[] = ""; static const char kBadString[] = "??"; -DIPrinter &DIPrinter::operator<<(const DILineInfo &Info) { +void DIPrinter::printName(const DILineInfo &Info, bool Inlined) { if (PrintFunctionNames) { std::string FunctionName = Info.FunctionName; if (FunctionName == kDILineInfoBadString) FunctionName = kBadString; - OS << FunctionName << "\n"; + + StringRef Delimiter = (PrintPretty == true) ? " at " : "\n"; + StringRef Prefix = (PrintPretty && Inlined) ? " (inlined by) " : ""; + OS << Prefix << FunctionName << Delimiter; } std::string Filename = Info.FileName; if (Filename == kDILineInfoBadString) Filename = kBadString; OS << Filename << ":" << Info.Line << ":" << Info.Column << "\n"; +} + +DIPrinter &DIPrinter::operator<<(const DILineInfo &Info) { + printName(Info, false); return *this; } DIPrinter &DIPrinter::operator<<(const DIInliningInfo &Info) { uint32_t FramesNum = Info.getNumberOfFrames(); - if (FramesNum == 0) - return (*this << DILineInfo()); - for (uint32_t i = 0; i < FramesNum; i++) { - *this << Info.getFrame(i); + if (FramesNum == 0) { + printName(DILineInfo(), false); + return *this; } + for (uint32_t i = 0; i < FramesNum; i++) + printName(Info.getFrame(i), i > 0); return *this; } diff --git a/test/tools/llvm-symbolizer/Inputs/addr.exe b/test/tools/llvm-symbolizer/Inputs/addr.exe index 0d9e87dd7232196dac17fe42d9135f0b6b1d19bb..d87569319e9275c8d520452f9148143ccbcf6cc8 100755 GIT binary patch delta 1405 zcma)6OKcNo5T1Y6yY>dhvGeHK#Bw&csZyuS)~y;>MUVwim7u7k2vjLjMT`N(DK>HJ zh;XQYLt8i?5{;1HfHFFHMzo*)T3g#m3|*>INp$1t#+-IH>Q1_V+18vmkHywrt=((&Bb;r`X@@;; z99PME=y~7Ln%cx(T-vBhXPPjR+^SvSVEZK~L0n?_b7mMBf|DFrRAur5!rV(8)* zoNCt-e-bKq?;=C%aW)j3Z`ZSNzF-iCm4=t2-Gnzn1o#KQ;_f@ZR-E0Wi$QEBeF(Ru z^~4c}*#Q2|J9JWGc#1e*vrbGCCkhFOMu+^cGhXLvee)EJNePI*61~qj<@tvg@NyqJ zGe+Q~*V`Ene}*yY=eZYsCt!KFJN)i+tI$GtUH%jDFLNDMC^tn>?!F|7=LeeXPwz{c4k+d9a(L4XQL$lY=5+}+A)yakUUuwNV{|pr8Of#4@Gr~ zh|ulJ2s)(Q6gtQdbP(C>5P=7~MCifj5PJzc2nB6!-M!0hci^%K-6cjYp!^bnOuphb0@7%f`u2@=ch zijGrzwINE46*QtGNH%$sWzRLBjXM1b4KaP!cgF^AR7qp15S)(%6Cvk$!lV#LmtCCi ze#C=BA!&ZU0%wmwm#Nc!ScvH~4IfP17<4QHWM|D;(9rTOlg13%s5qvo`hS*}ELv(2 zSxqoVcnABQ;jC-klb6@<$;qgYQC{19ju&7SbA97%o7dvF``L1;#R+x#Do-K%b=VSt a#&yF$mQ@nnQAwP!GzqErhTXjP7X1x}@x6%v diff --git a/test/tools/llvm-symbolizer/sym.test b/test/tools/llvm-symbolizer/sym.test index 559124a44c0..01a6692222e 100644 --- a/test/tools/llvm-symbolizer/sym.test +++ b/test/tools/llvm-symbolizer/sym.test @@ -1,19 +1,30 @@ #Source: ##include -#static inline int inc (int *a) { +#static inline int inctwo (int *a) { # printf ("%d\n",(*a)++); # return (*a)++; #} +#static inline int inc (int *a) { +# printf ("%d\n",inctwo(a)); +# return (*a)++; +#} +# # #int main () { # int x = 1; # return inc(&x); #} +# #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 -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: main -#CHECK: {{[/\]+}}tmp{{[/\]+}}x.c:9:0 +#CHECK: {{[/\]+}}tmp{{[/\]+}}x.c:14:0 +# +#PRETTY: {{[0x]+}}40054d: inctwo at {{[/\]+}}tmp{{[/\]+}}x.c:3:3 +#PRETTY: (inlined by) inc at {{[/\]+}}tmp{{[/\]+}}x.c:7:0 +#PRETTY (inlined by) main at {{[/\]+}}tmp{{[/\]+}}x.c:14:0 diff --git a/tools/llvm-symbolizer/llvm-symbolizer.cpp b/tools/llvm-symbolizer/llvm-symbolizer.cpp index d0ef51e6f17..e45660c84c7 100644 --- a/tools/llvm-symbolizer/llvm-symbolizer.cpp +++ b/tools/llvm-symbolizer/llvm-symbolizer.cpp @@ -78,6 +78,10 @@ static cl::opt ClPrintAddress("print-address", cl::init(false), cl::desc("Show address before line information")); +static cl::opt + ClPrettyPrint("pretty-print", cl::init(false), + cl::desc("Make the output more human friendly")); + static bool error(std::error_code ec) { if (!ec) return false; @@ -143,6 +147,7 @@ int main(int argc, char **argv) { cl::ParseCommandLineOptions(argc, argv, "llvm-symbolizer\n"); LLVMSymbolizer::Options Opts(ClPrintFunctions, ClUseSymbolTable, ClDemangle, ClUseRelativeAddress, ClDefaultArch); + for (const auto &hint : ClDsymHint) { if (sys::path::extension(hint) == ".dSYM") { Opts.DsymHints.push_back(hint); @@ -156,13 +161,15 @@ int main(int argc, char **argv) { bool IsData = false; std::string ModuleName; uint64_t ModuleOffset; - DIPrinter Printer(outs(), ClPrintFunctions != FunctionNameKind::None); + DIPrinter Printer(outs(), ClPrintFunctions != FunctionNameKind::None, + ClPrettyPrint); while (parseCommand(IsData, ModuleName, ModuleOffset)) { if (ClPrintAddress) { outs() << "0x"; outs().write_hex(ModuleOffset); - outs() << "\n"; + StringRef Delimiter = (ClPrettyPrint == true) ? ": " : "\n"; + outs() << Delimiter; } if (IsData) { auto ResOrErr = Symbolizer.symbolizeData(ModuleName, ModuleOffset); -- 2.34.1