Golang如何从runtime.Stack获取函数名称
Golang如何从runtime.Stack获取函数名称 我正在尝试寻找一种方法,能够打印出所有当前 goroutine 堆栈跟踪中存在的函数名称。
https://play.golang.org/p/VnLpAAZb_vm
在上面的示例中,我能够发现 main.main() 调用了 main.mine(),但我该如何提取该函数的名称?另外,我如何才能知道 main.another() 函数也被调用了呢?
我认为您要找的是 https://golang.org/pkg/runtime/#Callers,它允许您构建一个包含调用栈中函数指针的 []uintptr 切片。这里有一个示例:https://github.com/skillian/expr/blob/505e7bc29386b34d243efe6d7cf0d8146c76dc6c/errors/pc.go#L33
之后,您需要像这样使用 https://golang.org/pkg/runtime/#CallersFrames :https://github.com/skillian/expr/blob/505e7bc29386b34d243efe6d7cf0d8146c76dc6c/errors/pc.go#L47
更多关于Golang如何从runtime.Stack获取函数名称的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
可以通过 runtime.Stack 获取完整的堆栈跟踪信息,然后使用 runtime.CallersFrames 来解析每个调用帧,从而提取函数名称。以下是一个示例代码,展示了如何获取当前 goroutine 中所有函数的名称:
package main
import (
"fmt"
"runtime"
"strings"
)
func another() {
printStack()
}
func mine() {
another()
}
func printStack() {
buf := make([]byte, 1024)
n := runtime.Stack(buf, false)
stack := string(buf[:n])
// 解析堆栈跟踪
lines := strings.Split(stack, "\n")
for i, line := range lines {
// 函数名通常在奇数行(从0开始计数)
if i%2 == 1 && strings.Contains(line, "(") {
// 提取函数名部分
fn := strings.TrimSpace(line)
// 去除参数和地址信息
if idx := strings.Index(fn, "("); idx != -1 {
fn = fn[:idx]
}
fmt.Printf("函数: %s\n", fn)
}
}
}
func main() {
mine()
}
输出会包含类似这样的函数名称:
函数: runtime.Stack
函数: main.printStack
函数: main.another
函数: main.mine
函数: main.main
如果需要更精确的解析,可以使用 runtime.Callers 和 runtime.CallersFrames:
func printStackFrames() {
pcs := make([]uintptr, 32)
n := runtime.Callers(0, pcs)
frames := runtime.CallersFrames(pcs[:n])
for {
frame, more := frames.Next()
fmt.Printf("函数: %s\n", frame.Function)
if !more {
break
}
}
}
这种方法会从当前调用点开始回溯,显示调用链中的所有函数名称,包括 main.another()。

