Home | History | Annotate | Download | only in test
      1 // run -gcflags -l=4
      2 
      3 // Copyright 2017 The Go Authors. All rights reserved.
      4 // Use of this source code is governed by a BSD-style
      5 // license that can be found in the LICENSE file.
      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() // line 27
     28 }
     29 
     30 func g() {
     31 	h() // line 31
     32 }
     33 
     34 func h() {
     35 	x := &globalFrame
     36 	x.pc, x.file, x.line, x.ok = runtime.Caller(skip) // line 36
     37 }
     38 
     39 //go:noinline
     40 func testCaller(skp int) frame {
     41 	skip = skp
     42 	f() // line 42
     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 // -1 means don't care
     56 var expected = []wantFrame{
     57 	0: {"main.testCaller", 36},
     58 	1: {"main.testCaller", 31},
     59 	2: {"main.testCaller", 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) // line 68
     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