github.com/llvm-mirror/llgo@v0.0.0-20190322182713-bf6f0a60fce1/third_party/gotools/go/ssa/interp/testdata/callstack.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"path"
     6  	"runtime"
     7  	"strings"
     8  )
     9  
    10  var stack string
    11  
    12  func f() {
    13  	pc := make([]uintptr, 6)
    14  	pc = pc[:runtime.Callers(1, pc)]
    15  	for _, f := range pc {
    16  		Func := runtime.FuncForPC(f)
    17  		name := Func.Name()
    18  		if strings.Contains(name, "$") || strings.Contains(name, ".func") {
    19  			name = "func" // anon funcs vary across toolchains
    20  		}
    21  		file, line := Func.FileLine(0)
    22  		stack += fmt.Sprintf("%s at %s:%d\n", name, path.Base(file), line)
    23  	}
    24  }
    25  
    26  func g() { f() }
    27  func h() { g() }
    28  func i() { func() { h() }() }
    29  
    30  // Hack: the 'func' and the call to Caller are on the same line,
    31  // to paper over differences between toolchains.
    32  // (The interpreter's location info isn't yet complete.)
    33  func runtimeCaller0() (uintptr, string, int, bool) { return runtime.Caller(0) }
    34  
    35  func main() {
    36  	i()
    37  	if stack != `main.f at callstack.go:12
    38  main.g at callstack.go:26
    39  main.h at callstack.go:27
    40  func at callstack.go:28
    41  main.i at callstack.go:28
    42  main.main at callstack.go:35
    43  ` {
    44  		panic("unexpected stack: " + stack)
    45  	}
    46  
    47  	pc, file, line, _ := runtimeCaller0()
    48  	got := fmt.Sprintf("%s @ %s:%d", runtime.FuncForPC(pc).Name(), path.Base(file), line)
    49  	if got != "main.runtimeCaller0 @ callstack.go:33" {
    50  		panic("runtime.Caller: " + got)
    51  	}
    52  }