Source file
test/inline_callers.go
1
2
3
4
5
6
7 package main
8
9 import (
10 "fmt"
11 "runtime"
12 )
13
14 var skip int
15 var npcs int
16 var pcs = make([]uintptr, 32)
17
18 func f() {
19 g()
20 }
21
22 func g() {
23 h()
24 }
25
26 func h() {
27 npcs = runtime.Callers(skip, pcs)
28 }
29
30 func testCallers(skp int) (frames []string) {
31 skip = skp
32 f()
33 for i := 0; i < npcs; i++ {
34 fn := runtime.FuncForPC(pcs[i] - 1)
35 frames = append(frames, fn.Name())
36 if fn.Name() == "main.main" {
37 break
38 }
39 }
40 return
41 }
42
43 func testCallersFrames(skp int) (frames []string) {
44 skip = skp
45 f()
46 callers := pcs[:npcs]
47 ci := runtime.CallersFrames(callers)
48 for {
49 frame, more := ci.Next()
50 frames = append(frames, frame.Function)
51 if !more || frame.Function == "main.main" {
52 break
53 }
54 }
55 return
56 }
57
58 var expectedFrames [][]string = [][]string{
59 0: {"runtime.Callers", "main.h", "main.g", "main.f", "main.testCallers", "main.main"},
60 1: {"main.h", "main.g", "main.f", "main.testCallers", "main.main"},
61 2: {"main.g", "main.f", "main.testCallers", "main.main"},
62 3: {"main.f", "main.testCallers", "main.main"},
63 4: {"main.testCallers", "main.main"},
64 5: {"main.main"},
65 }
66
67 var allFrames = []string{"runtime.Callers", "main.h", "main.g", "main.f", "main.testCallersFrames", "main.main"}
68
69 func same(xs, ys []string) bool {
70 if len(xs) != len(ys) {
71 return false
72 }
73 for i := range xs {
74 if xs[i] != ys[i] {
75 return false
76 }
77 }
78 return true
79 }
80
81 func main() {
82 for i := 0; i <= 5; i++ {
83 frames := testCallers(i)
84 expected := expectedFrames[i]
85 if !same(frames, expected) {
86 fmt.Printf("testCallers(%d):\n got %v\n want %v\n", i, frames, expected)
87 }
88
89 frames = testCallersFrames(i)
90 expected = allFrames[i:]
91 if !same(frames, expected) {
92 fmt.Printf("testCallersFrames(%d):\n got %v\n want %v\n", i, frames, expected)
93 }
94 }
95 }
96
View as plain text