[llvm] r257236 - [llvm-symbolizer] -print-source-context-lines option to print source code around the line.

Benjamin Kramer via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 11 05:31:30 PST 2016


On Mon, Jan 11, 2016 at 2:25 PM, Manuel Klimek via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> On Sat, Jan 9, 2016 at 1:18 AM Mike Aizatsky via llvm-commits
> <llvm-commits at lists.llvm.org> wrote:
>>
>> Author: aizatsky
>> Date: Fri Jan  8 18:14:35 2016
>> New Revision: 257236
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=257236&view=rev
>> Log:
>> [llvm-symbolizer] -print-source-context-lines option to print source code
>> around the line.
>>
>> Differential Revision: http://reviews.llvm.org/D15909
>>
>> Added:
>>     llvm/trunk/test/tools/llvm-symbolizer/print_context.c
>> Modified:
>>     llvm/trunk/include/llvm/DebugInfo/Symbolize/DIPrinter.h
>>     llvm/trunk/lib/DebugInfo/Symbolize/DIPrinter.cpp
>>     llvm/trunk/test/lit.cfg
>>     llvm/trunk/tools/llvm-symbolizer/llvm-symbolizer.cpp
>>
>> Modified: llvm/trunk/include/llvm/DebugInfo/Symbolize/DIPrinter.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/Symbolize/DIPrinter.h?rev=257236&r1=257235&r2=257236&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/include/llvm/DebugInfo/Symbolize/DIPrinter.h (original)
>> +++ llvm/trunk/include/llvm/DebugInfo/Symbolize/DIPrinter.h Fri Jan  8
>> 18:14:35 2016
>> @@ -28,13 +28,16 @@ class DIPrinter {
>>    raw_ostream &OS;
>>    bool PrintFunctionNames;
>>    bool PrintPretty;
>> -  void printName(const DILineInfo &Info, bool Inlined);
>> +  int PrintSourceContext;
>> +
>> +  void print(const DILineInfo &Info, bool Inlined);
>> +  void printContext(std::string FileName, int64_t Line);
>>
>>  public:
>>    DIPrinter(raw_ostream &OS, bool PrintFunctionNames = true,
>> -            bool PrintPretty = false)
>> +            bool PrintPretty = false, int PrintSourceContext = 0)
>>        : OS(OS), PrintFunctionNames(PrintFunctionNames),
>> -        PrintPretty(PrintPretty) {}
>> +        PrintPretty(PrintPretty), PrintSourceContext(PrintSourceContext)
>> {}
>>
>>    DIPrinter &operator<<(const DILineInfo &Info);
>>    DIPrinter &operator<<(const DIInliningInfo &Info);
>>
>> Modified: llvm/trunk/lib/DebugInfo/Symbolize/DIPrinter.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/Symbolize/DIPrinter.cpp?rev=257236&r1=257235&r2=257236&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/DebugInfo/Symbolize/DIPrinter.cpp (original)
>> +++ llvm/trunk/lib/DebugInfo/Symbolize/DIPrinter.cpp Fri Jan  8 18:14:35
>> 2016
>> @@ -15,6 +15,7 @@
>>  #include "llvm/DebugInfo/Symbolize/DIPrinter.h"
>>
>>  #include "llvm/DebugInfo/DIContext.h"
>> +#include "llvm/Support/LineIterator.h"
>>
>>  namespace llvm {
>>  namespace symbolize {
>> @@ -24,7 +25,36 @@ namespace symbolize {
>>  static const char kDILineInfoBadString[] = "<invalid>";
>>  static const char kBadString[] = "??";
>>
>> -void DIPrinter::printName(const DILineInfo &Info, bool Inlined) {
>> +// Prints source code around in the FileName the Line.
>> +void DIPrinter::printContext(std::string FileName, int64_t Line) {
>> +  if (PrintSourceContext <= 0)
>> +    return;
>> +
>> +  ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
>> +      MemoryBuffer::getFile(FileName);
>> +  if (!BufOrErr)
>> +    return;
>> +
>> +  std::unique_ptr<MemoryBuffer> Buf = std::move(BufOrErr.get());
>> +  int64_t FirstLine = std::max(1l, Line - PrintSourceContext / 2);
>> +  int64_t LastLine = FirstLine + PrintSourceContext;
>> +  size_t MaxLineNumberWidth = std::ceil(std::log10(LastLine));
>> +
>> +  for (line_iterator I = line_iterator(*Buf, false);
>> +       !I.is_at_eof() && I.line_number() <= LastLine; ++I) {
>> +    int64_t L = I.line_number();
>> +    if (L >= FirstLine && L <= LastLine) {
>> +      OS << format_decimal(L, MaxLineNumberWidth);
>> +      if (L == Line)
>> +        OS << " >: ";
>> +      else
>> +        OS << "  : ";
>> +      OS << *I << "\n";
>> +    }
>> +  }
>> +}
>> +
>> +void DIPrinter::print(const DILineInfo &Info, bool Inlined) {
>>    if (PrintFunctionNames) {
>>      std::string FunctionName = Info.FunctionName;
>>      if (FunctionName == kDILineInfoBadString)
>> @@ -38,21 +68,22 @@ void DIPrinter::printName(const DILineIn
>>    if (Filename == kDILineInfoBadString)
>>      Filename = kBadString;
>>    OS << Filename << ":" << Info.Line << ":" << Info.Column << "\n";
>> +  printContext(Filename, Info.Line);
>>  }
>>
>>  DIPrinter &DIPrinter::operator<<(const DILineInfo &Info) {
>> -  printName(Info, false);
>> +  print(Info, false);
>>    return *this;
>>  }
>>
>>  DIPrinter &DIPrinter::operator<<(const DIInliningInfo &Info) {
>>    uint32_t FramesNum = Info.getNumberOfFrames();
>>    if (FramesNum == 0) {
>> -    printName(DILineInfo(), false);
>> +    print(DILineInfo(), false);
>>      return *this;
>>    }
>>    for (uint32_t i = 0; i < FramesNum; i++)
>> -    printName(Info.getFrame(i), i > 0);
>> +    print(Info.getFrame(i), i > 0);
>>    return *this;
>>  }
>>
>>
>> Modified: llvm/trunk/test/lit.cfg
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/lit.cfg?rev=257236&r1=257235&r2=257236&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/test/lit.cfg (original)
>> +++ llvm/trunk/test/lit.cfg Fri Jan  8 18:14:35 2016
>> @@ -194,6 +194,7 @@ config.substitutions.append( ('%llvmshli
>>  config.substitutions.append( ('%shlibext', config.llvm_shlib_ext) )
>>  config.substitutions.append( ('%exeext', config.llvm_exe_ext) )
>>  config.substitutions.append( ('%python', config.python_executable) )
>> +config.substitutions.append( ('%host_cc', config.host_cc) )
>>
>>  # OCaml substitutions.
>>  # Support tests for both native and bytecode builds.
>> @@ -276,6 +277,7 @@ for pattern in [r"\bbugpoint\b(?!-)",
>>                  r"\bllvm-split\b",
>>                  r"\bllvm-tblgen\b",
>>                  r"\bllvm-c-test\b",
>> +                NOJUNK + r"\bllvm-symbolizer\b",
>>                  NOJUNK + r"\bopt\b",
>>                  r"\bFileCheck\b",
>>                  r"\bobj2yaml\b",
>>
>> Added: llvm/trunk/test/tools/llvm-symbolizer/print_context.c
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-symbolizer/print_context.c?rev=257236&view=auto
>>
>> ==============================================================================
>> --- llvm/trunk/test/tools/llvm-symbolizer/print_context.c (added)
>> +++ llvm/trunk/test/tools/llvm-symbolizer/print_context.c Fri Jan  8
>> 18:14:35 2016
>> @@ -0,0 +1,22 @@
>> +// REQUIRES: x86_64-linux
>> +// RUN: %host_cc -O0 -g %s -o %t 2>&1
>
>
> It seems brittle to have tests depend on the host compiler.
>
> Benjamin apparently has ideas for alternatives.

What the other symbolizer tests seem to have binaries checked in,
which isn't very pretty either. I think the best way for this kind of
test in LLVM is to use yaml2obj, but I'm not sure if that can handle
executables.

>>
>> +// RUN: %t 2>&1 | llvm-symbolizer -print-source-context-lines=5 -obj=%t |
>> FileCheck %s --check-prefix=CHECK
>> +
>> +#include <stdio.h>
>> +
>> +int inc(int a) {
>> +  return a + 1;
>> +}
>> +
>> +int main() {
>> +  printf("%p\n", inc);
>> +  return 0;
>> +}
>> +
>> +// CHECK: inc
>> +// CHECK: print_context.c:7
>> +// CHECK: 5  : #include
>> +// CHECK: 6  :
>> +// CHECK: 7 >: int inc
>> +// CHECK: 8  :   return
>> +// CHECK: 9  : }
>>
>> Modified: llvm/trunk/tools/llvm-symbolizer/llvm-symbolizer.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-symbolizer/llvm-symbolizer.cpp?rev=257236&r1=257235&r2=257236&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/tools/llvm-symbolizer/llvm-symbolizer.cpp (original)
>> +++ llvm/trunk/tools/llvm-symbolizer/llvm-symbolizer.cpp Fri Jan  8
>> 18:14:35 2016
>> @@ -82,6 +82,10 @@ static cl::opt<bool>
>>      ClPrettyPrint("pretty-print", cl::init(false),
>>                    cl::desc("Make the output more human friendly"));
>>
>> +static cl::opt<int> ClPrintSourceContextLines(
>> +    "print-source-context-lines", cl::init(0),
>> +    cl::desc("Print N number of source file context"));
>> +
>>  static bool error(std::error_code ec) {
>>    if (!ec)
>>      return false;
>> @@ -155,7 +159,7 @@ int main(int argc, char **argv) {
>>    LLVMSymbolizer Symbolizer(Opts);
>>
>>    DIPrinter Printer(outs(), ClPrintFunctions != FunctionNameKind::None,
>> -                    ClPrettyPrint);
>> +                    ClPrettyPrint, ClPrintSourceContextLines);
>>
>>    const int kMaxInputStringLength = 1024;
>>    char InputString[kMaxInputStringLength];
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>


More information about the llvm-commits mailing list