[Symbolizer]: Add -pretty-print option
Differential Revision: http://reviews.llvm.org/D13671 llvm-svn: 252798
This commit is contained in:
@@ -56,6 +56,14 @@ EXAMPLE
|
|||||||
|
|
||||||
foo(int)
|
foo(int)
|
||||||
/tmp/a.cc:12
|
/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
|
OPTIONS
|
||||||
-------
|
-------
|
||||||
@@ -101,6 +109,10 @@ OPTIONS
|
|||||||
.. option:: -print-address
|
.. option:: -print-address
|
||||||
Print address before the source code location. Defaults to false.
|
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
|
EXIT STATUS
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
|||||||
@@ -27,10 +27,14 @@ namespace symbolize {
|
|||||||
class DIPrinter {
|
class DIPrinter {
|
||||||
raw_ostream &OS;
|
raw_ostream &OS;
|
||||||
bool PrintFunctionNames;
|
bool PrintFunctionNames;
|
||||||
|
bool PrintPretty;
|
||||||
|
void printName(const DILineInfo &Info, bool Inlined);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DIPrinter(raw_ostream &OS, bool PrintFunctionNames = true)
|
DIPrinter(raw_ostream &OS, bool PrintFunctionNames = true,
|
||||||
: OS(OS), PrintFunctionNames(PrintFunctionNames) {}
|
bool PrintPretty = false)
|
||||||
|
: OS(OS), PrintFunctionNames(PrintFunctionNames),
|
||||||
|
PrintPretty(PrintPretty) {}
|
||||||
|
|
||||||
DIPrinter &operator<<(const DILineInfo &Info);
|
DIPrinter &operator<<(const DILineInfo &Info);
|
||||||
DIPrinter &operator<<(const DIInliningInfo &Info);
|
DIPrinter &operator<<(const DIInliningInfo &Info);
|
||||||
|
|||||||
@@ -24,27 +24,35 @@ namespace symbolize {
|
|||||||
static const char kDILineInfoBadString[] = "<invalid>";
|
static const char kDILineInfoBadString[] = "<invalid>";
|
||||||
static const char kBadString[] = "??";
|
static const char kBadString[] = "??";
|
||||||
|
|
||||||
DIPrinter &DIPrinter::operator<<(const DILineInfo &Info) {
|
void DIPrinter::printName(const DILineInfo &Info, bool Inlined) {
|
||||||
if (PrintFunctionNames) {
|
if (PrintFunctionNames) {
|
||||||
std::string FunctionName = Info.FunctionName;
|
std::string FunctionName = Info.FunctionName;
|
||||||
if (FunctionName == kDILineInfoBadString)
|
if (FunctionName == kDILineInfoBadString)
|
||||||
FunctionName = kBadString;
|
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;
|
std::string Filename = Info.FileName;
|
||||||
if (Filename == kDILineInfoBadString)
|
if (Filename == kDILineInfoBadString)
|
||||||
Filename = kBadString;
|
Filename = kBadString;
|
||||||
OS << Filename << ":" << Info.Line << ":" << Info.Column << "\n";
|
OS << Filename << ":" << Info.Line << ":" << Info.Column << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
DIPrinter &DIPrinter::operator<<(const DILineInfo &Info) {
|
||||||
|
printName(Info, false);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
DIPrinter &DIPrinter::operator<<(const DIInliningInfo &Info) {
|
DIPrinter &DIPrinter::operator<<(const DIInliningInfo &Info) {
|
||||||
uint32_t FramesNum = Info.getNumberOfFrames();
|
uint32_t FramesNum = Info.getNumberOfFrames();
|
||||||
if (FramesNum == 0)
|
if (FramesNum == 0) {
|
||||||
return (*this << DILineInfo());
|
printName(DILineInfo(), false);
|
||||||
for (uint32_t i = 0; i < FramesNum; i++) {
|
return *this;
|
||||||
*this << Info.getFrame(i);
|
|
||||||
}
|
}
|
||||||
|
for (uint32_t i = 0; i < FramesNum; i++)
|
||||||
|
printName(Info.getFrame(i), i > 0);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -1,19 +1,30 @@
|
|||||||
#Source:
|
#Source:
|
||||||
##include <stdio.h>
|
##include <stdio.h>
|
||||||
#static inline int inc (int *a) {
|
#static inline int inctwo (int *a) {
|
||||||
# printf ("%d\n",(*a)++);
|
# printf ("%d\n",(*a)++);
|
||||||
# return (*a)++;
|
# return (*a)++;
|
||||||
#}
|
#}
|
||||||
|
#static inline int inc (int *a) {
|
||||||
|
# printf ("%d\n",inctwo(a));
|
||||||
|
# return (*a)++;
|
||||||
|
#}
|
||||||
|
#
|
||||||
#
|
#
|
||||||
#int main () {
|
#int main () {
|
||||||
# int x = 1;
|
# int x = 1;
|
||||||
# return inc(&x);
|
# return inc(&x);
|
||||||
#}
|
#}
|
||||||
|
#
|
||||||
#Build as : clang -g -O2 addr.c
|
#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: 0x40054d
|
||||||
#CHECK: main
|
#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
|
||||||
|
|
||||||
|
|||||||
@@ -78,6 +78,10 @@ static cl::opt<bool>
|
|||||||
ClPrintAddress("print-address", cl::init(false),
|
ClPrintAddress("print-address", cl::init(false),
|
||||||
cl::desc("Show address before line information"));
|
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) {
|
static bool error(std::error_code ec) {
|
||||||
if (!ec)
|
if (!ec)
|
||||||
return false;
|
return false;
|
||||||
@@ -143,6 +147,7 @@ int main(int argc, char **argv) {
|
|||||||
cl::ParseCommandLineOptions(argc, argv, "llvm-symbolizer\n");
|
cl::ParseCommandLineOptions(argc, argv, "llvm-symbolizer\n");
|
||||||
LLVMSymbolizer::Options Opts(ClPrintFunctions, ClUseSymbolTable, ClDemangle,
|
LLVMSymbolizer::Options Opts(ClPrintFunctions, ClUseSymbolTable, ClDemangle,
|
||||||
ClUseRelativeAddress, ClDefaultArch);
|
ClUseRelativeAddress, ClDefaultArch);
|
||||||
|
|
||||||
for (const auto &hint : ClDsymHint) {
|
for (const auto &hint : ClDsymHint) {
|
||||||
if (sys::path::extension(hint) == ".dSYM") {
|
if (sys::path::extension(hint) == ".dSYM") {
|
||||||
Opts.DsymHints.push_back(hint);
|
Opts.DsymHints.push_back(hint);
|
||||||
@@ -156,13 +161,15 @@ int main(int argc, char **argv) {
|
|||||||
bool IsData = false;
|
bool IsData = false;
|
||||||
std::string ModuleName;
|
std::string ModuleName;
|
||||||
uint64_t ModuleOffset;
|
uint64_t ModuleOffset;
|
||||||
DIPrinter Printer(outs(), ClPrintFunctions != FunctionNameKind::None);
|
DIPrinter Printer(outs(), ClPrintFunctions != FunctionNameKind::None,
|
||||||
|
ClPrettyPrint);
|
||||||
|
|
||||||
while (parseCommand(IsData, ModuleName, ModuleOffset)) {
|
while (parseCommand(IsData, ModuleName, ModuleOffset)) {
|
||||||
if (ClPrintAddress) {
|
if (ClPrintAddress) {
|
||||||
outs() << "0x";
|
outs() << "0x";
|
||||||
outs().write_hex(ModuleOffset);
|
outs().write_hex(ModuleOffset);
|
||||||
outs() << "\n";
|
StringRef Delimiter = (ClPrettyPrint == true) ? ": " : "\n";
|
||||||
|
outs() << Delimiter;
|
||||||
}
|
}
|
||||||
if (IsData) {
|
if (IsData) {
|
||||||
auto ResOrErr = Symbolizer.symbolizeData(ModuleName, ModuleOffset);
|
auto ResOrErr = Symbolizer.symbolizeData(ModuleName, ModuleOffset);
|
||||||
|
|||||||
Reference in New Issue
Block a user