From f77c42faa6e1feb4bd4ab03351b9787c0c1c52ba Mon Sep 17 00:00:00 2001 From: Kalyana Chadalavada Date: Fri, 8 Mar 2019 19:29:08 -0800 Subject: [PATCH] test for printing demangled names in disassembly --- internal/binutils/binutils.go | 8 ++ internal/report/report.go | 8 +- internal/report/report_test.go | 111 ++++++++++++++++++++++ internal/report/testdata/README.md | 8 ++ internal/report/testdata/disasm.bin | Bin 0 -> 9064 bytes internal/report/testdata/disasm.mac.bin | Bin 0 -> 15796 bytes internal/report/testdata/sample/disasm.cc | 24 +++++ 7 files changed, 158 insertions(+), 1 deletion(-) create mode 100755 internal/report/testdata/disasm.bin create mode 100755 internal/report/testdata/disasm.mac.bin create mode 100644 internal/report/testdata/sample/disasm.cc diff --git a/internal/binutils/binutils.go b/internal/binutils/binutils.go index 967726d1f..5c97eb477 100644 --- a/internal/binutils/binutils.go +++ b/internal/binutils/binutils.go @@ -163,6 +163,14 @@ func (bu *Binutils) Disasm(file string, start, end uint64) ([]plugin.Inst, error fmt.Sprintf("--start-address=%#x", start), fmt.Sprintf("--stop-address=%#x", end), file) + + if runtime.GOOS == "darwin" { + cmd = exec.Command(b.objdump, "-disassemble-all", "-no-show-raw-insn", + "-line-numbers", fmt.Sprintf("-start-address=%#x", start), + fmt.Sprintf("-stop-address=%#x", end), + file) + } + out, err := cmd.Output() if err != nil { return nil, fmt.Errorf("%v: %v", cmd.Args, err) diff --git a/internal/report/report.go b/internal/report/report.go index 90b34a18b..c40e713cc 100644 --- a/internal/report/report.go +++ b/internal/report/report.go @@ -432,7 +432,13 @@ func PrintAssembly(w io.Writer, rpt *Report, obj plugin.ObjTool, maxFuncs int) e ns := annotateAssembly(insts, sns, s.base) - fmt.Fprintf(w, "ROUTINE ======================== %s\n", demangle.Filter(s.sym.Name[0], options...)) + if strings.HasPrefix(s.sym.Name[0], "__Z") { + // Workaround to handle double leading underscores on Mac + // which are not properly handled by the demangle.Filter + fmt.Fprintf(w, "ROUTINE ======================== %s\n", demangle.Filter(s.sym.Name[0][1:], options...)) + } else { + fmt.Fprintf(w, "ROUTINE ======================== %s\n", demangle.Filter(s.sym.Name[0], options...)) + } for _, name := range s.sym.Name[1:] { fmt.Fprintf(w, " AKA ======================== %s\n", name) } diff --git a/internal/report/report_test.go b/internal/report/report_test.go index 7c4363fad..86b170bd6 100644 --- a/internal/report/report_test.go +++ b/internal/report/report_test.go @@ -17,8 +17,11 @@ package report import ( "bytes" "io/ioutil" + "os/exec" "regexp" "runtime" + "strconv" + "strings" "testing" "github.com/google/pprof/internal/binutils" @@ -100,6 +103,15 @@ var testM = []*profile.Mapping{ HasLineNumbers: true, HasInlineFrames: true, }, + { + // Entry for disassembly demangle test + ID: 2, + File: "testdata/disasm.bin", + HasFunctions: true, + HasFilenames: true, + HasLineNumbers: true, + HasInlineFrames: true, + }, } var testF = []*profile.Function{ @@ -123,6 +135,12 @@ var testF = []*profile.Function{ Name: "tee", Filename: "/some/path/testdata/source2", }, + { + // Entry for disassembly demangle test + ID: 5, + Name: "_ZStL8__ioinit", + Filename: "testdata/sample/disasm.cc", + }, } var testL = []*profile.Location{ @@ -176,6 +194,19 @@ var testL = []*profile.Location{ }, }, }, + { + // Entry for disassembly demangle test + ID: 6, + Mapping: testM[1], + // Update the following address if the binary disasm.bin is rebuilt + Address: 2101617, + Line: []profile.Line{ + { + Function: testF[4], + Line: 2, + }, + }, + }, } var testProfile = &profile.Profile{ @@ -213,6 +244,86 @@ var testProfile = &profile.Profile{ Mapping: testM, } +func TestPrintAssembly(t *testing.T) { + + if runtime.GOOS != "linux" && runtime.GOOS != "darwin" { + t.Skip("This test only works on Linux or Mac") + } + + demangled := "ioinit" + + if runtime.GOOS == "darwin" { + // get objdump version and skip test if < 9.0 + // binutils does not export get(). Try to get objdump version on our own. + // only works if objdump is in path. + cmdOut, err := exec.Command("objdump", "-version").Output() + if err != nil { + t.Fatalf("cannot determine objdump version. %s", err) + } + + re := regexp.MustCompile(`.*version (([0-9]*)\.([0-9]*)\.([0-9]*)).*$`) + fields := re.FindStringSubmatch(strings.Split(string(cmdOut), "\n")[0]) + if len(fields) != 5 { + t.Fatalf("cannot determine objdump version. %s", fields) + } + + if ver, _ := strconv.Atoi(fields[2]); ver < 9 { + t.Skip("objdump version too old. ", fields[0]) + } + + testM[1].File = "testdata/disasm.mac.bin" + testM[1].Start = 0x100000000 + testL[5].Address = 0 + testF[4].Name = "__ZNSt3__111char_traitsIcE11eq_int_typeEii" + // Update the following address if the binary, disasm.mac.bin is rebuilt + testL[5].Address = 0x100001cd0 + demangled = "eq_int_type" + } + + sampleValue1 := func(v []int64) int64 { + return v[1] + } + + asmProfile := testProfile.Copy() + asmProfile.Sample = []*profile.Sample{ + { + Location: []*profile.Location{testL[5]}, + Value: []int64{1, 1000}, + }, + } + + tc := testcase{ + rpt: New( + asmProfile, + &Options{ + OutputFormat: Dis, + Symbol: regexp.MustCompile(`.`), + TrimPath: "/some/path", + SampleValue: sampleValue1, + }, + ), + want: demangled, + } + + var b bytes.Buffer + if err := Generate(&b, tc.rpt, &binutils.Binutils{}); err != nil { + t.Fatalf("%s: %v", tc.want, err) + } + + r := regexp.MustCompile(`( *ROUTINE.*={24} )(.*)`) + fields := r.FindStringSubmatch(b.String()) + if len(fields) != 3 { + t.Fatalf("want: %s\n got: %s\n", tc.want, string(b.String())) + } + + demangledName := fields[2] + + if !(strings.Contains(demangledName, tc.want)) || + (strings.Contains(demangledName, "_Z")) { + t.Fatalf("want: %s\n got: %s\n", tc.want, string(b.String())) + } +} + func TestDisambiguation(t *testing.T) { parent1 := &graph.Node{Info: graph.NodeInfo{Name: "parent1"}} parent2 := &graph.Node{Info: graph.NodeInfo{Name: "parent2"}} diff --git a/internal/report/testdata/README.md b/internal/report/testdata/README.md index 2b60fcca6..eee3b7ef7 100644 --- a/internal/report/testdata/README.md +++ b/internal/report/testdata/README.md @@ -8,3 +8,11 @@ To update the binary and profile: go build -o sample.bin ./sample ./sample.bin -cpuprofile sample.cpu ``` + +To update the binary used for PrintAssembly test: +```shell +g++ -o disasm[.mac].bin disasm.cc +``` + +The address for testL[5] need to be manually updated +with the new adddess for the corresponding symbols diff --git a/internal/report/testdata/disasm.bin b/internal/report/testdata/disasm.bin new file mode 100755 index 0000000000000000000000000000000000000000..6f30db148ffba906183005b65a306d1643e4da53 GIT binary patch literal 9064 zcmeHNeQaCR6~B&?CZ&zzLc>xR)N~-VR5eMPlys;N=c~_K+J+{DvQb_g+es|^(b>l1qk(zO(0ewCT$Y@Gj$Rhg-jhx`=dx>FvcV{jVY~Q3WK4rm3qH(-#O0n zv%Mkq&!p|5_}ue5pZC7|?z{JtuMZ3j)_FWinpfSZh&$70BRwpbznnWDJ*rzR$M2Qu z3bhP;y~b>Lk4+%8+akLb+QhgQlzeZrTqSHKC+SZTKB4M*YT&x(6EUafgK!1)W6=WtyzF}Ahyx@2rqGLg1`&IsE0Qok}#5w-jb1Wlsir6Va%dBd&w+s7z9HDq=>g z_*BBej1e=QNJo;1Lzoql^mqbOkwjYU7z+3HnVW-~gI#ui-#&9ou+yIYI;?)LqE$|R z)T94sy?fL~JR@1Z`O6Z^Ngn0rMsn)P`)h4@1Y1s>%CKDaGuemEaOauk0IZY}JOZ!O zo^|2JSfPj4i|7mga!Wwl(O$zLHGjr|m$pzy-f-Z~efw<(?%cQL9k|4%01FPBQ`d19 z9XN0O8khA>F=fvnK^u>YK5sPN(gF@#_EeIsci{X<)F$l?oVRL?8#C`V8AlsZO#x** zbjqqLo-t;A-ZZCW^i%A51ft?KkKwmvZ4Y|HPm<{D+eNf%zC}Du?b$P$e}H&O_3SCl zA0nQn`0TTqzZU%XG4Q%|ycaIKdWTW?qcQWRh2hbm*@lZ?Ys@x33YW(0_CG_b*!r8s zfcmgyZNG*>aIn{yZP*5CY+E!6?^tUvgqNU0LulS#e0x0Dvi3pkfBzh1y~M+%hwNs% z{to@U#)b>9H(tEpH3|#Hi}N=bp3}yw7pyiooMwkB$zd&jhqwP0?o|FdV`lqq7{Dd+ zS!o>I{s_4FW(;}Wz|ZN1=b-1IbPiKuAI!le#zX4+&yGWbdUzWC!hPqBLVf`mw%SvW zAV()I6pKdTC8YJ&Wk|np+9Z-(%g?dWG@_5wZA`4h-&|J>62g>DVq5-Jo!dqa3u z*ZAu7qu6vQ=t#KmQMmBh&;}Yslkwsw-uWj!LA;0FvjQEzlldDeoEs{9)DI8E)o&Ry za~@;c@AKzq&3$!$==RY5&>bOj?$}bi53m%qKVFp{dJBwrGMNe7n#m?(S0PEy<=z_% zP#a{>H ztxox{ZBH?u$6q_-agz7?{NJhT^|d|h9qwA6czujQ?+K((VeBCpRJAFM_Uw6pY z9`dd4^#z~@{a#;_-q-6fZ~NefUi$yH|Lqx&@3(xf<@<~!qMMsu!hqmcxOh5SP?K-s zFn`qedZRvEZp+u$q;yY`>z|xEE@QczAL#v{Chy$eE)+AwALm6(-(hNtd^lKUv+5Mf z~Fa7SO? z7X$12<70_PI&gh(OR#-Y*9N=ec3r`Hagvn#zf(x3V!1b$<6dRSL^}jt+$?3iIbf`n zhSEAK$Cs7XV>#ZaI@DTaW7T}s_I`-+84_8SC{S+<#;RVCjlp<`(Aaa zlKX^H=%u%n-|KR`O?6krm+rUa`m#$cq4av!tM_ppD{r(P)+yi82F79_8t;(}g7K>u zm;IPwbv-&B+_w*|3TTM86E&#u%K4%DJjIoLUK` z(EGKY%J+`0UDfJDCu`uZ*TCPefnTb}vgM%XjDEEbWhXzQoYy`1#Kvyf3*?-%v(9UolWV!?w z&E@qJfiJIVR<9iP^yoqz7w0OVpNnI*C|>natr?405xZQ8iE@@QUE?xQ{FTQ>Wm~G1x`LXqT*jQlQlRSa(nGKp zk2#jhNgP)l*yZLk7lmDZ;xsg+g1PCG6&VAyvNoNRULuX6_CXa)XRLTI)EnMpMJAY= zNaurN`2_x9BN070>3d=*t)rvTQsVAp`CmOj;_aCnJb% za3TX1HDvtKn+&ClPB<8!IoyzFrgru9$$G|!5_Cn7=;3q~9p-8uZyXP} Vgc4VDSJkk8lQ-T*mw}5_{{+McZ2$lO literal 0 HcmV?d00001 diff --git a/internal/report/testdata/disasm.mac.bin b/internal/report/testdata/disasm.mac.bin new file mode 100755 index 0000000000000000000000000000000000000000..e3bd32a77547adf47f71ce1d199d0e73fd7a0c86 GIT binary patch literal 15796 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 + +using namespace std; +int main(int argc, char** argv) { + cout << "Hello World!" << endl; + return 0; +}