Golang如何从runtime.Stack获取函数名称

Golang如何从runtime.Stack获取函数名称 我正在尝试寻找一种方法,能够打印出所有当前 goroutine 堆栈跟踪中存在的函数名称。

https://play.golang.org/p/VnLpAAZb_vm

在上面的示例中,我能够发现 main.main() 调用了 main.mine(),但我该如何提取该函数的名称?另外,我如何才能知道 main.another() 函数也被调用了呢?

2 回复

更多关于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.Callersruntime.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()

回到顶部