llvm.org GIT mirror llvm / d9750d3
[llvm-symbolizer] -print-source-context-lines option to print source code around the line. Differential Revision: http://reviews.llvm.org/D15909 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@257236 91177308-0d34-0410-b5e6-96231b3b80d8 Mike Aizatsky 4 years ago
5 changed file(s) with 70 addition(s) and 8 deletion(s). Raw diff Collapse all Expand all
2727 raw_ostream &OS;
2828 bool PrintFunctionNames;
2929 bool PrintPretty;
30 void printName(const DILineInfo &Info, bool Inlined);
30 int PrintSourceContext;
31
32 void print(const DILineInfo &Info, bool Inlined);
33 void printContext(std::string FileName, int64_t Line);
3134
3235 public:
3336 DIPrinter(raw_ostream &OS, bool PrintFunctionNames = true,
34 bool PrintPretty = false)
37 bool PrintPretty = false, int PrintSourceContext = 0)
3538 : OS(OS), PrintFunctionNames(PrintFunctionNames),
36 PrintPretty(PrintPretty) {}
39 PrintPretty(PrintPretty), PrintSourceContext(PrintSourceContext) {}
3740
3841 DIPrinter &operator<<(const DILineInfo &Info);
3942 DIPrinter &operator<<(const DIInliningInfo &Info);
1414 #include "llvm/DebugInfo/Symbolize/DIPrinter.h"
1515
1616 #include "llvm/DebugInfo/DIContext.h"
17 #include "llvm/Support/LineIterator.h"
1718
1819 namespace llvm {
1920 namespace symbolize {
2324 static const char kDILineInfoBadString[] = "";
2425 static const char kBadString[] = "??";
2526
26 void DIPrinter::printName(const DILineInfo &Info, bool Inlined) {
27 // Prints source code around in the FileName the Line.
28 void DIPrinter::printContext(std::string FileName, int64_t Line) {
29 if (PrintSourceContext <= 0)
30 return;
31
32 ErrorOr> BufOrErr =
33 MemoryBuffer::getFile(FileName);
34 if (!BufOrErr)
35 return;
36
37 std::unique_ptr Buf = std::move(BufOrErr.get());
38 int64_t FirstLine = std::max(1l, Line - PrintSourceContext / 2);
39 int64_t LastLine = FirstLine + PrintSourceContext;
40 size_t MaxLineNumberWidth = std::ceil(std::log10(LastLine));
41
42 for (line_iterator I = line_iterator(*Buf, false);
43 !I.is_at_eof() && I.line_number() <= LastLine; ++I) {
44 int64_t L = I.line_number();
45 if (L >= FirstLine && L <= LastLine) {
46 OS << format_decimal(L, MaxLineNumberWidth);
47 if (L == Line)
48 OS << " >: ";
49 else
50 OS << " : ";
51 OS << *I << "\n";
52 }
53 }
54 }
55
56 void DIPrinter::print(const DILineInfo &Info, bool Inlined) {
2757 if (PrintFunctionNames) {
2858 std::string FunctionName = Info.FunctionName;
2959 if (FunctionName == kDILineInfoBadString)
3767 if (Filename == kDILineInfoBadString)
3868 Filename = kBadString;
3969 OS << Filename << ":" << Info.Line << ":" << Info.Column << "\n";
70 printContext(Filename, Info.Line);
4071 }
4172
4273 DIPrinter &DIPrinter::operator<<(const DILineInfo &Info) {
43 printName(Info, false);
74 print(Info, false);
4475 return *this;
4576 }
4677
4778 DIPrinter &DIPrinter::operator<<(const DIInliningInfo &Info) {
4879 uint32_t FramesNum = Info.getNumberOfFrames();
4980 if (FramesNum == 0) {
50 printName(DILineInfo(), false);
81 print(DILineInfo(), false);
5182 return *this;
5283 }
5384 for (uint32_t i = 0; i < FramesNum; i++)
54 printName(Info.getFrame(i), i > 0);
85 print(Info.getFrame(i), i > 0);
5586 return *this;
5687 }
5788
193193 config.substitutions.append( ('%shlibext', config.llvm_shlib_ext) )
194194 config.substitutions.append( ('%exeext', config.llvm_exe_ext) )
195195 config.substitutions.append( ('%python', config.python_executable) )
196 config.substitutions.append( ('%host_cc', config.host_cc) )
196197
197198 # OCaml substitutions.
198199 # Support tests for both native and bytecode builds.
275276 r"\bllvm-split\b",
276277 r"\bllvm-tblgen\b",
277278 r"\bllvm-c-test\b",
279 NOJUNK + r"\bllvm-symbolizer\b",
278280 NOJUNK + r"\bopt\b",
279281 r"\bFileCheck\b",
280282 r"\bobj2yaml\b",
0 // REQUIRES: x86_64-linux
1 // RUN: %host_cc -O0 -g %s -o %t 2>&1
2 // RUN: %t 2>&1 | llvm-symbolizer -print-source-context-lines=5 -obj=%t | FileCheck %s --check-prefix=CHECK
3
4 #include
5
6 int inc(int a) {
7 return a + 1;
8 }
9
10 int main() {
11 printf("%p\n", inc);
12 return 0;
13 }
14
15 // CHECK: inc
16 // CHECK: print_context.c:7
17 // CHECK: 5 : #include
18 // CHECK: 6 :
19 // CHECK: 7 >: int inc
20 // CHECK: 8 : return
21 // CHECK: 9 : }
8080 static cl::opt
8181 ClPrettyPrint("pretty-print", cl::init(false),
8282 cl::desc("Make the output more human friendly"));
83
84 static cl::opt ClPrintSourceContextLines(
85 "print-source-context-lines", cl::init(0),
86 cl::desc("Print N number of source file context"));
8387
8488 static bool error(std::error_code ec) {
8589 if (!ec)
154158 LLVMSymbolizer Symbolizer(Opts);
155159
156160 DIPrinter Printer(outs(), ClPrintFunctions != FunctionNameKind::None,
157 ClPrettyPrint);
161 ClPrettyPrint, ClPrintSourceContextLines);
158162
159163 const int kMaxInputStringLength = 1024;
160164 char InputString[kMaxInputStringLength];