Source file
src/runtime/start_line_test.go
1
2
3
4
5 package runtime_test
6
7 import (
8 "fmt"
9 "internal/testenv"
10 "runtime"
11 "testing"
12 )
13
14
15
16
17
18
19
20
21 func normalFunc() int {
22 return callerStartLine(false)
23 }
24
25 func multilineDeclarationFunc() int {
26 return multilineDeclarationFunc1(0, 0, 0)
27 }
28
29
30 func multilineDeclarationFunc1(
31 a, b, c int) int {
32 return callerStartLine(false)
33 }
34
35 func blankLinesFunc() int {
36
37
38
39
40
41
42 return callerStartLine(false)
43 }
44
45 func inlineFunc() int {
46 return inlineFunc1()
47 }
48
49 func inlineFunc1() int {
50 return callerStartLine(true)
51 }
52
53 var closureFn func() int
54
55 func normalClosure() int {
56
57 closureFn = func() int {
58 return callerStartLine(false)
59 }
60 return closureFn()
61 }
62
63 func inlineClosure() int {
64 return func() int {
65 return callerStartLine(true)
66 }()
67 }
68
69 func TestStartLine(t *testing.T) {
70
71
72 testenv.SkipIfOptimizationOff(t)
73
74 testCases := []struct {
75 name string
76 fn func() int
77 want int
78 }{
79 {
80 name: "normal",
81 fn: normalFunc,
82 want: 21,
83 },
84 {
85 name: "multiline-declaration",
86 fn: multilineDeclarationFunc,
87 want: 30,
88 },
89 {
90 name: "blank-lines",
91 fn: blankLinesFunc,
92 want: 35,
93 },
94 {
95 name: "inline",
96 fn: inlineFunc,
97 want: 49,
98 },
99 {
100 name: "normal-closure",
101 fn: normalClosure,
102 want: 57,
103 },
104 {
105 name: "inline-closure",
106 fn: inlineClosure,
107 want: 64,
108 },
109 }
110
111 for _, tc := range testCases {
112 t.Run(tc.name, func(t *testing.T) {
113 got := tc.fn()
114 if got != tc.want {
115 t.Errorf("start line got %d want %d", got, tc.want)
116 }
117 })
118 }
119 }
120
121
122 func callerStartLine(wantInlined bool) int {
123 var pcs [1]uintptr
124 n := runtime.Callers(2, pcs[:])
125 if n != 1 {
126 panic(fmt.Sprintf("no caller of callerStartLine? n = %d", n))
127 }
128
129 frames := runtime.CallersFrames(pcs[:])
130 frame, _ := frames.Next()
131
132 inlined := frame.Func == nil
133 if wantInlined != inlined {
134 panic(fmt.Sprintf("caller %s inlined got %v want %v", frame.Function, inlined, wantInlined))
135 }
136
137 return runtime.FrameStartLine(&frame)
138 }
139
View as plain text