github.com/likebike/go--@v0.0.0-20190911215757-0bd925d16e96/go/src/runtime/callers_test.go (about) 1 // Copyright 2016 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package runtime_test 6 7 import ( 8 "runtime" 9 "strings" 10 "testing" 11 ) 12 13 func f1(pan bool) []uintptr { 14 return f2(pan) // line 14 15 } 16 17 func f2(pan bool) []uintptr { 18 return f3(pan) // line 18 19 } 20 21 func f3(pan bool) []uintptr { 22 if pan { 23 panic("f3") // line 23 24 } 25 ret := make([]uintptr, 20) 26 return ret[:runtime.Callers(0, ret)] // line 26 27 } 28 29 func testCallers(t *testing.T, pcs []uintptr, pan bool) { 30 m := make(map[string]int, len(pcs)) 31 frames := runtime.CallersFrames(pcs) 32 for { 33 frame, more := frames.Next() 34 if frame.Function != "" { 35 m[frame.Function] = frame.Line 36 } 37 if !more { 38 break 39 } 40 } 41 42 var seen []string 43 for k := range m { 44 seen = append(seen, k) 45 } 46 t.Logf("functions seen: %s", strings.Join(seen, " ")) 47 48 var f3Line int 49 if pan { 50 f3Line = 23 51 } else { 52 f3Line = 26 53 } 54 want := []struct { 55 name string 56 line int 57 }{ 58 {"f1", 14}, 59 {"f2", 18}, 60 {"f3", f3Line}, 61 } 62 for _, w := range want { 63 if got := m["runtime_test."+w.name]; got != w.line { 64 t.Errorf("%s is line %d, want %d", w.name, got, w.line) 65 } 66 } 67 } 68 69 func TestCallers(t *testing.T) { 70 testCallers(t, f1(false), false) 71 } 72 73 func TestCallersPanic(t *testing.T) { 74 defer func() { 75 if r := recover(); r == nil { 76 t.Fatal("did not panic") 77 } 78 pcs := make([]uintptr, 20) 79 pcs = pcs[:runtime.Callers(0, pcs)] 80 testCallers(t, pcs, true) 81 }() 82 f1(true) 83 }