1
2
3
4
5 package dwarfgen
6
7 import (
8 "debug/dwarf"
9 "internal/platform"
10 "internal/testenv"
11 "io"
12 "runtime"
13 "testing"
14 )
15
16 func TestIssue75249(t *testing.T) {
17 testenv.MustHaveGoRun(t)
18 t.Parallel()
19
20 if !platform.ExecutableHasDWARF(runtime.GOOS, runtime.GOARCH) {
21 t.Skipf("skipping on %s/%s: no DWARF symbol table in executables", runtime.GOOS, runtime.GOARCH)
22 }
23
24 code := `
25 package main
26
27 type Data struct {
28 Field1 int
29 Field2 *int
30 Field3 int
31 Field4 *int
32 Field5 int
33 Field6 *int
34 Field7 int
35 Field8 *int
36 }
37
38 //go:noinline
39 func InitializeData(d *Data) {
40 d.Field1++ // line 16
41 d.Field2 = d.Field4
42 d.Field3++
43 d.Field4 = d.Field6
44 d.Field5++
45 d.Field6 = d.Field8
46 d.Field7++
47 d.Field8 = d.Field2 // line 23
48 }
49
50 func main() {
51 var data Data
52 InitializeData(&data)
53 }
54 `
55
56 _, f := gobuild(t, t.TempDir(), true, []testline{{line: code}})
57 defer f.Close()
58
59 dwarfData, err := f.DWARF()
60 if err != nil {
61 t.Fatal(err)
62 }
63 dwarfReader := dwarfData.Reader()
64
65 for {
66 entry, err := dwarfReader.Next()
67 if err != nil {
68 t.Fatal(err)
69 }
70 if entry == nil {
71 break
72 }
73 if entry.Tag != dwarf.TagCompileUnit {
74 continue
75 }
76 name := entry.AttrField(dwarf.AttrName)
77 if name == nil || name.Class != dwarf.ClassString || name.Val != "main" {
78 continue
79 }
80 lr, err := dwarfData.LineReader(entry)
81 if err != nil {
82 t.Fatal(err)
83 }
84 stmts := map[int]bool{}
85 for {
86 var le dwarf.LineEntry
87 err := lr.Next(&le)
88 if err == io.EOF {
89 break
90 }
91 if err != nil {
92 t.Fatal(err)
93 }
94 if !le.IsStmt {
95 continue
96 }
97 stmts[le.Line] = true
98 }
99 for i := 16; i <= 23; i++ {
100 if !stmts[i] {
101 t.Errorf("missing statement at line %d", i)
102 }
103 }
104 }
105 }
106
View as plain text