Source file
test/inline_caller.go
1
2
3
4
5
6
7 package main
8
9 import (
10 "fmt"
11 "runtime"
12 )
13
14 type frame struct {
15 pc uintptr
16 file string
17 line int
18 ok bool
19 }
20
21 var (
22 skip int
23 globalFrame frame
24 )
25
26 func f() {
27 g()
28 }
29
30 func g() {
31 h()
32 }
33
34 func h() {
35 x := &globalFrame
36 x.pc, x.file, x.line, x.ok = runtime.Caller(skip)
37 }
38
39
40 func testCaller(skp int) frame {
41 skip = skp
42 f()
43 frame := globalFrame
44 if !frame.ok {
45 panic(fmt.Sprintf("skip=%d runtime.Caller failed", skp))
46 }
47 return frame
48 }
49
50 type wantFrame struct {
51 funcName string
52 line int
53 }
54
55
56 var expected = []wantFrame{
57 0: {"main.h", 36},
58 1: {"main.g", 31},
59 2: {"main.f", 27},
60 3: {"main.testCaller", 42},
61 4: {"main.main", 68},
62 5: {"runtime.main", -1},
63 6: {"runtime.goexit", -1},
64 }
65
66 func main() {
67 for i := 0; i <= 6; i++ {
68 frame := testCaller(i)
69 fn := runtime.FuncForPC(frame.pc)
70 if expected[i].line >= 0 && frame.line != expected[i].line {
71 panic(fmt.Sprintf("skip=%d expected line %d, got line %d", i, expected[i].line, frame.line))
72 }
73 if fn.Name() != expected[i].funcName {
74 panic(fmt.Sprintf("skip=%d expected function %s, got %s", i, expected[i].funcName, fn.Name()))
75 }
76 }
77 }
78
View as plain text