[Symbolizer]: Add -pretty-print option
authorHemant Kulkarni <khemant@codeaurora.org>
Wed, 11 Nov 2015 17:47:54 +0000 (17:47 +0000)
committerHemant Kulkarni <khemant@codeaurora.org>
Wed, 11 Nov 2015 17:47:54 +0000 (17:47 +0000)
 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
include/llvm/DebugInfo/Symbolize/DIPrinter.h
lib/DebugInfo/Symbolize/DIPrinter.cpp
test/tools/llvm-symbolizer/Inputs/addr.exe
test/tools/llvm-symbolizer/sym.test
tools/llvm-symbolizer/llvm-symbolizer.cpp

index 9d6571d5c4c2a954c6dfb7b4adcad347670d4b2c..dfbf4919abe2cab1a9871bdb5102f42323252381 100644 (file)
@@ -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
 -----------
 
index 6e192253d5dda4c975a7d3e9057a77ec1426d8d7..0703fb14da61507d5b0ebddc794f66ab200c290f 100644 (file)
@@ -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);
index ad5f693d77e4cbfcc1a2062b6231c90f084bfb46..c6bfbc07dcf307f9c547fabc74b72ce66284278d 100644 (file)
@@ -24,27 +24,35 @@ namespace symbolize {
 static const char kDILineInfoBadString[] = "<invalid>";
 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;
 }
 
index 0d9e87dd7232196dac17fe42d9135f0b6b1d19bb..d87569319e9275c8d520452f9148143ccbcf6cc8 100755 (executable)
Binary files a/test/tools/llvm-symbolizer/Inputs/addr.exe and b/test/tools/llvm-symbolizer/Inputs/addr.exe differ
index 559124a44c048251f56b3f10170fe47651077e75..01a6692222e728168e6ceb02f7718e2b3d82a34f 100644 (file)
@@ -1,19 +1,30 @@
 #Source:
 ##include <stdio.h>
-#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
 
index d0ef51e6f17221860e8b62c67856f38b1b7569b7..e45660c84c7723c5923b547bd5639c308a867f8b 100644 (file)
@@ -78,6 +78,10 @@ static cl::opt<bool>
     ClPrintAddress("print-address", cl::init(false),
                    cl::desc("Show address before line information"));
 
+static cl::opt<bool>
+    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);