diff options
Diffstat (limited to 'test/inline_callers.go')
-rw-r--r-- | test/inline_callers.go | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/test/inline_callers.go b/test/inline_callers.go new file mode 100644 index 0000000..ee7d647 --- /dev/null +++ b/test/inline_callers.go @@ -0,0 +1,95 @@ +// run -gcflags=-l=4 + +// Copyright 2017 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "fmt" + "runtime" +) + +var skip int +var npcs int +var pcs = make([]uintptr, 32) + +func f() { + g() +} + +func g() { + h() +} + +func h() { + npcs = runtime.Callers(skip, pcs) +} + +func testCallers(skp int) (frames []string) { + skip = skp + f() + for i := 0; i < npcs; i++ { + fn := runtime.FuncForPC(pcs[i] - 1) + frames = append(frames, fn.Name()) + if fn.Name() == "main.main" { + break + } + } + return +} + +func testCallersFrames(skp int) (frames []string) { + skip = skp + f() + callers := pcs[:npcs] + ci := runtime.CallersFrames(callers) + for { + frame, more := ci.Next() + frames = append(frames, frame.Function) + if !more || frame.Function == "main.main" { + break + } + } + return +} + +var expectedFrames [][]string = [][]string{ + 0: {"runtime.Callers", "main.h", "main.g", "main.f", "main.testCallers", "main.main"}, + 1: {"main.h", "main.g", "main.f", "main.testCallers", "main.main"}, + 2: {"main.g", "main.f", "main.testCallers", "main.main"}, + 3: {"main.f", "main.testCallers", "main.main"}, + 4: {"main.testCallers", "main.main"}, + 5: {"main.main"}, +} + +var allFrames = []string{"runtime.Callers", "main.h", "main.g", "main.f", "main.testCallersFrames", "main.main"} + +func same(xs, ys []string) bool { + if len(xs) != len(ys) { + return false + } + for i := range xs { + if xs[i] != ys[i] { + return false + } + } + return true +} + +func main() { + for i := 0; i <= 5; i++ { + frames := testCallers(i) + expected := expectedFrames[i] + if !same(frames, expected) { + fmt.Printf("testCallers(%d):\n got %v\n want %v\n", i, frames, expected) + } + + frames = testCallersFrames(i) + expected = allFrames[i:] + if !same(frames, expected) { + fmt.Printf("testCallersFrames(%d):\n got %v\n want %v\n", i, frames, expected) + } + } +} |