Index: test/tools/llvm-symbolizer/output-style-empty-line.test =================================================================== --- /dev/null +++ test/tools/llvm-symbolizer/output-style-empty-line.test @@ -0,0 +1,19 @@ +This test checks that with --output-style=GNU the tool does not print an empty +line after the report for an address. The current behavior is preserved for +--output-style=LLVM or if the option is omitted. + +RUN: llvm-symbolizer -e %p/Inputs/addr.exe < %p/Inputs/addr.inp \ +RUN: | FileCheck %s --check-prefix=LLVM + +RUN: llvm-symbolizer --output-style=LLVM -e %p/Inputs/addr.exe < %p/Inputs/addr.inp \ +RUN: | FileCheck %s --check-prefix=LLVM + +RUN: llvm-symbolizer --output-style=GNU -e %p/Inputs/addr.exe < %p/Inputs/addr.inp \ +RUN: | FileCheck %s --check-prefix=GNU + +LLVM: x.c:14:0 +LLVM-EMPTY: +LLVM-NEXT: some text2 + +GNU: x.c:14 +GNU-NEXT: some text2 Index: test/tools/llvm-symbolizer/output-style-inlined.test =================================================================== --- /dev/null +++ test/tools/llvm-symbolizer/output-style-inlined.test @@ -0,0 +1,17 @@ +This test checks that when inlined frames are not shown (-i=0) and the output +style is set to GNU (--output-style=GNU) the name of an inlined function is not +replaced with the name of the top caller function. At the same time, the current +behavior of llvm-symbolizer is preserved with --output-style=LLVM or when +the option is not specified. + +RUN: llvm-symbolizer -i=0 -e %p/Inputs/addr.exe 0x40054d \ +RUN: | FileCheck %s --check-prefix=LLVM + +RUN: llvm-symbolizer --output-style=LLVM -i=0 -e %p/Inputs/addr.exe 0x40054d \ +RUN: | FileCheck %s --check-prefix=LLVM + +RUN: llvm-symbolizer --output-style=GNU -i=0 -e %p/Inputs/addr.exe 0x40054d \ +RUN: | FileCheck %s --check-prefix=GNU + +LLVM: main +GNU: inctwo Index: tools/llvm-symbolizer/llvm-symbolizer.cpp =================================================================== --- tools/llvm-symbolizer/llvm-symbolizer.cpp +++ tools/llvm-symbolizer/llvm-symbolizer.cpp @@ -227,13 +227,25 @@ ModuleName, {Offset, object::SectionedAddress::UndefSection}, ClDwpName); Printer << (error(ResOrErr) ? DIInliningInfo() : ResOrErr.get()); + } else if (ClOutputStyle == DIPrinter::OutputStyle::GNU) { + // With ClPrintFunctions == FunctionNameKind::LinkageName (default) + // and ClUseSymbolTable == true (also default), Symbolizer.symbolizeCode() + // may override the name of an inlined function with the name of the topmost + // caller function in the inlining chain. This contradicts the existing + // behavior of addr2line. Symbolizer.symbolizeInlinedCode() overrides only + // the topmost function, which suits our needs better. + auto ResOrErr = Symbolizer.symbolizeInlinedCode( + ModuleName, {Offset, object::SectionedAddress::UndefSection}, + ClDwpName); + Printer << (error(ResOrErr) ? DILineInfo() : ResOrErr.get().getFrame(0)); } else { auto ResOrErr = Symbolizer.symbolizeCode( ModuleName, {Offset, object::SectionedAddress::UndefSection}, ClDwpName); Printer << (error(ResOrErr) ? DILineInfo() : ResOrErr.get()); } - outs() << "\n"; + if (ClOutputStyle == DIPrinter::OutputStyle::LLVM) + outs() << "\n"; outs().flush(); }