Source file test/inline_callers.go

     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  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