Index: test/tools/llvm-symbolizer/output-style.test =================================================================== --- test/tools/llvm-symbolizer/output-style.test +++ test/tools/llvm-symbolizer/output-style.test @@ -1,11 +1,87 @@ -RUN: llvm-symbolizer -e %p/Inputs/addr.exe 0x40054d \ -RUN: | FileCheck %s --check-prefix=LLVM +RUN: llvm-symbolizer -i -e %p/Inputs/addr.exe < %p/Inputs/addr.inp \ +RUN: | FileCheck %s --check-prefix=LLVM_I -RUN: llvm-symbolizer --output-style=GNU -e %p/Inputs/addr.exe 0x40054d \ -RUN: | FileCheck %s --check-prefix=GNU +RUN: llvm-symbolizer --output-style=LLVM -i -e %p/Inputs/addr.exe < %p/Inputs/addr.inp \ +RUN: | FileCheck %s --check-prefix=LLVM_I -RUN: llvm-symbolizer --output-style=LLVM -e %p/Inputs/addr.exe 0x40054d \ -RUN: | FileCheck %s --check-prefix=LLVM +LLVM_I: some text +LLVM_I-NEXT: inctwo{{$}} +LLVM_I-NEXT: {{\\|/}}tmp{{\\|/}}x.c:3:3{{$}} +LLVM_I-NEXT: inc{{$}} +LLVM_I-NEXT: {{\\|/}}tmp{{\\|/}}x.c:7:0{{$}} +LLVM_I-NEXT: main{{$}} +LLVM_I-NEXT: {{\\|/}}tmp{{\\|/}}x.c:14:0{{$}} +LLVM_I-EMPTY: +LLVM_I-NEXT: some text2 -LLVM: {{^}}/tmp{{\\|/}}x.c:3:3{{$}} -GNU: {{^}}/tmp{{\\|/}}x.c:3{{$}} +RUN: llvm-symbolizer --output-style=GNU -i -e %p/Inputs/addr.exe < %p/Inputs/addr.inp \ +RUN: | FileCheck %s --check-prefix=GNU_I + +GNU_I: some text +GNU_I-NEXT: inctwo{{$}} +GNU_I-NEXT: {{\\|/}}tmp{{\\|/}}x.c:3{{$}} +GNU_I-NEXT: inc{{$}} +GNU_I-NEXT: {{\\|/}}tmp{{\\|/}}x.c:7{{$}} +GNU_I-NEXT: main{{$}} +GNU_I-NEXT: {{\\|/}}tmp{{\\|/}}x.c:14{{$}} +GNU_I-NEXT: some text2 + +RUN: llvm-symbolizer -i=0 -e %p/Inputs/addr.exe < %p/Inputs/addr.inp \ +RUN: | FileCheck %s --check-prefix=LLVM_NI + +RUN: llvm-symbolizer --output-style=LLVM -i=0 -e %p/Inputs/addr.exe < %p/Inputs/addr.inp \ +RUN: | FileCheck %s --check-prefix=LLVM_NI + +LLVM_NI: some text +LLVM_NI-NEXT: main{{$}} +LLVM_NI-NEXT: {{\\|/}}tmp{{\\|/}}x.c:3:3{{$}} +LLVM_NI-EMPTY: +LLVM_NI-NEXT: some text2 + +RUN: llvm-symbolizer --output-style=GNU -i=0 -e %p/Inputs/addr.exe < %p/Inputs/addr.inp \ +RUN: | FileCheck %s --check-prefix=GNU_NI + +GNU_NI: some text +GNU_NI-NEXT: inctwo{{$}} +GNU_NI-NEXT: {{\\|/}}tmp{{\\|/}}x.c:3{{$}} +GNU_NI-NEXT: some text2 + +RUN: llvm-symbolizer -i -p -e %p/Inputs/addr.exe < %p/Inputs/addr.inp \ +RUN: | FileCheck %s --check-prefix=LLVM_I_P + +RUN: llvm-symbolizer --output-style=LLVM -i -p -e %p/Inputs/addr.exe < %p/Inputs/addr.inp \ +RUN: | FileCheck %s --check-prefix=LLVM_I_P + +LLVM_I_P: some text +LLVM_I_P-NEXT: inctwo at {{\\|/}}tmp{{\\|/}}x.c:3:3{{$}} +LLVM_I_P-NEXT: (inlined by) inc at {{\\|/}}tmp{{\\|/}}x.c:7:0{{$}} +LLVM_I_P-NEXT: (inlined by) main at {{\\|/}}tmp{{\\|/}}x.c:14:0{{$}} +LLVM_I_P-EMPTY: +LLVM_I_P-NEXT: some text2 + +RUN: llvm-symbolizer --output-style=GNU -i -p -e %p/Inputs/addr.exe < %p/Inputs/addr.inp \ +RUN: | FileCheck %s --check-prefix=GNU_I_P + +GNU_I_P: some text +GNU_I_P-NEXT: inctwo at {{\\|/}}tmp{{\\|/}}x.c:3{{$}} +GNU_I_P-NEXT: (inlined by) inc at {{\\|/}}tmp{{\\|/}}x.c:7{{$}} +GNU_I_P-NEXT: (inlined by) main at {{\\|/}}tmp{{\\|/}}x.c:14{{$}} +GNU_I_P-NEXT: some text2 + +RUN: llvm-symbolizer -i=0 -p -e %p/Inputs/addr.exe < %p/Inputs/addr.inp \ +RUN: | FileCheck %s --check-prefix=LLVM_NI_P + +RUN: llvm-symbolizer --output-style=LLVM -i=0 -p -e %p/Inputs/addr.exe < %p/Inputs/addr.inp \ +RUN: | FileCheck %s --check-prefix=LLVM_NI_P + +LLVM_NI_P: some text +LLVM_NI_P-NEXT: main at {{\\|/}}tmp{{\\|/}}x.c:3:3{{$}} +LLVM_NI_P-EMPTY: +LLVM_NI_P-NEXT: some text2 + +RUN: llvm-symbolizer --output-style=GNU -i=0 -p -e %p/Inputs/addr.exe < %p/Inputs/addr.inp \ +RUN: | FileCheck %s --check-prefix=GNU_NI_P + +GNU_NI_P: some text +GNU_NI_P-NEXT: inctwo at {{\\|/}}tmp{{\\|/}}x.c:3{{$}} +GNU_NI_P-NEXT: some text2 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(); }