对于一些需求,我们可能需要获取运行时的函数栈帧,典型的场景就是实现error发生时,错误堆栈信息的获取。
通过runtime包的Callers函数就可以实现需求。
其函数原型如下:
func Callers(skip int, pc []uintptr) int- skip:即跳过的前几个栈帧。因为栈帧是从新到旧的,并且
Callers函数本身这样的函数也有栈帧,而对我们并没有帮助,所以使用此参数跳过不必要的栈帧。 - pc:用来存储每个栈帧中的程序计数器
使用实例,我们有一个函数getStack用来获取调用该函数位置时的栈帧,那么对应的代码如下:
type stack []uintptr
func getStack() *stack {
const depth = 32
var pcs [depth]uintptr
// 这里的2表示跳过Callers本身的栈帧和getStack的栈帧
n := runtime.Callers(2, pcs[:])
var st stack = pcs[:n]
return &st
}