From eae4e99f7877f1bcf103e02ce9e4b593c7499c7c Mon Sep 17 00:00:00 2001 From: Derek Parker Date: Thu, 18 Sep 2014 23:00:41 -0500 Subject: [PATCH] Cleanup dwarf/frame tests --- dwarf/_helper/helper.go | 67 ------------------------ dwarf/frame/frame_entries_test.go | 84 ++++++++++++++++++++++++++---- dwarf/frame/frame_parser_test.go | 14 ++++- dwarf/frame/testdata/frame | Bin 0 -> 71584 bytes 4 files changed, 86 insertions(+), 79 deletions(-) delete mode 100644 dwarf/_helper/helper.go create mode 100644 dwarf/frame/testdata/frame diff --git a/dwarf/_helper/helper.go b/dwarf/_helper/helper.go deleted file mode 100644 index c7aee263..00000000 --- a/dwarf/_helper/helper.go +++ /dev/null @@ -1,67 +0,0 @@ -package dwarfhelper - -import ( - "debug/elf" - "debug/gosym" - "os" - "path/filepath" - "testing" -) - -func GosymData(testfile string, t testing.TB) *gosym.Table { - f, err := os.Open(testfile) - if err != nil { - t.Fatal(err) - } - - e, err := elf.NewFile(f) - if err != nil { - t.Fatal(err) - } - - return parseGoSym(t, e) -} - -func GrabDebugFrameSection(fp string, t testing.TB) []byte { - p, err := filepath.Abs(fp) - if err != nil { - t.Fatal(err) - } - - f, err := os.Open(p) - if err != nil { - t.Fatal(err) - } - - ef, err := elf.NewFile(f) - if err != nil { - t.Fatal(err) - } - - data, err := ef.Section(".debug_frame").Data() - if err != nil { - t.Fatal(err) - } - - return data -} - -func parseGoSym(t testing.TB, exe *elf.File) *gosym.Table { - symdat, err := exe.Section(".gosymtab").Data() - if err != nil { - t.Fatal(err) - } - - pclndat, err := exe.Section(".gopclntab").Data() - if err != nil { - t.Fatal(err) - } - - pcln := gosym.NewLineTable(pclndat, exe.Section(".text").Addr) - tab, err := gosym.NewTable(symdat, pcln) - if err != nil { - t.Fatal(err) - } - - return tab -} diff --git a/dwarf/frame/frame_entries_test.go b/dwarf/frame/frame_entries_test.go index 4b83a22d..e1fa2fda 100644 --- a/dwarf/frame/frame_entries_test.go +++ b/dwarf/frame/frame_entries_test.go @@ -1,12 +1,72 @@ package frame import ( + "debug/elf" + "debug/gosym" + "io/ioutil" + "os" "path/filepath" "testing" - - "github.com/derekparker/dbg/dwarf/_helper" ) +func gosymData(testfile string, t testing.TB) *gosym.Table { + f, err := os.Open(testfile) + if err != nil { + t.Fatal(err) + } + + e, err := elf.NewFile(f) + if err != nil { + t.Fatal(err) + } + + return parseGoSym(t, e) +} + +func grabDebugFrameSection(fp string, t testing.TB) []byte { + p, err := filepath.Abs(fp) + if err != nil { + t.Fatal(err) + } + + f, err := os.Open(p) + if err != nil { + t.Fatal(err) + } + + ef, err := elf.NewFile(f) + if err != nil { + t.Fatal(err) + } + + data, err := ef.Section(".debug_frame").Data() + if err != nil { + t.Fatal(err) + } + + return data +} + +func parseGoSym(t testing.TB, exe *elf.File) *gosym.Table { + symdat, err := exe.Section(".gosymtab").Data() + if err != nil { + t.Fatal(err) + } + + pclndat, err := exe.Section(".gopclntab").Data() + if err != nil { + t.Fatal(err) + } + + pcln := gosym.NewLineTable(pclndat, exe.Section(".text").Addr) + tab, err := gosym.NewTable(symdat, pcln) + if err != nil { + t.Fatal(err) + } + + return tab +} + func TestFDEForPC(t *testing.T) { fde1 := &FrameDescriptionEntry{AddressRange: &addrange{begin: 100, end: 200}} fde2 := &FrameDescriptionEntry{AddressRange: &addrange{begin: 50, end: 99}} @@ -30,16 +90,20 @@ func TestFDEForPC(t *testing.T) { } func BenchmarkFDEForPC(b *testing.B) { - var ( - testfile, _ = filepath.Abs("../../_fixtures/testnextprog") - dbframe = dwarfhelper.GrabDebugFrameSection(testfile, b) - fdes = Parse(dbframe) - gsd = dwarfhelper.GosymData(testfile, b) - ) + f, err := os.Open("testdata/frame") + if err != nil { + b.Fatal(err) + } + defer f.Close() - pc, _, _ := gsd.LineToPC("/usr/local/go/src/pkg/runtime/memmove_amd64.s", 33) + data, err := ioutil.ReadAll(f) + if err != nil { + b.Fatal(err) + } + fdes := Parse(data) for i := 0; i < b.N; i++ { - _, _ = fdes.FDEForPC(pc) + // bench worst case, exhaustive search + _, _ = fdes.FDEForPC(0x455555555) } } diff --git a/dwarf/frame/frame_parser_test.go b/dwarf/frame/frame_parser_test.go index 9f109220..7b4c4b6d 100644 --- a/dwarf/frame/frame_parser_test.go +++ b/dwarf/frame/frame_parser_test.go @@ -1,16 +1,26 @@ package frame_test import ( + "io/ioutil" + "os" "testing" "github.com/davecheney/profile" - "github.com/derekparker/dbg/dwarf/_helper" "github.com/derekparker/dbg/dwarf/frame" ) func BenchmarkParse(b *testing.B) { defer profile.Start(profile.CPUProfile).Stop() - data := dwarfhelper.GrabDebugFrameSection("../../_fixtures/testprog", nil) + f, err := os.Open("testdata/frame") + if err != nil { + b.Fatal(err) + } + defer f.Close() + + data, err := ioutil.ReadAll(f) + if err != nil { + b.Fatal(err) + } b.ResetTimer() for i := 0; i < b.N; i++ { diff --git a/dwarf/frame/testdata/frame b/dwarf/frame/testdata/frame new file mode 100644 index 0000000000000000000000000000000000000000..a500558a794af6f1ffe315af9f1379b436d2e5ff GIT binary patch literal 71584 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 lgf_@_od&+5fv;@f>ow4vmm>{>^lUZIf(BZ