Golang Go语言中方便打印某个函数下的函数调用链路的工具?

就像这篇文章介绍的,打印 main 函数的调用链路,最终结果如下:

g[01]:  ->main.A1
g[01]:      ->main.B1
g[01]:          ->main.C1
g[01]:              ->main.D

目前知道有go-callvis,但是它是基于静态代码分析的,所以得到的结果会很杂乱。而上面说的那种方法,需要用代码生成工具给每个函数插入一行 defer 代码。有没有非侵入式的办法?个人感觉用 ebpf 是可以实现的。


Golang Go语言中方便打印某个函数下的函数调用链路的工具?

更多关于Golang Go语言中方便打印某个函数下的函数调用链路的工具?的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

runtime.Stack 啊,Frame 可以有更多选项

更多关于Golang Go语言中方便打印某个函数下的函数调用链路的工具?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


runtime.Stack 打印的是上游调用,我想看它的下游调用

这个不能静态实现吧? pprof 那个看起来比较靠谱,callvis 就算了吧

在Go语言中,若你想方便地打印某个函数下的函数调用链路(即调用栈),通常可以使用标准库中的runtimedebug包。以下是几种常见的方法来实现这一功能:

  1. 使用runtime.Stackruntime.Stack函数可以打印当前goroutine的完整调用栈。你可以在需要的地方调用它,将输出重定向到日志或标准输出。例如:

    package main
    
    import (
        "fmt"
        "runtime"
    )
    
    func printCallStack() {
        buf := make([]byte, 1024)
        n := runtime.Stack(buf, false)
        fmt.Println(string(buf[:n]))
    }
    
    func foo() {
        printCallStack()
    }
    
    func main() {
        foo()
    }
    
  2. 使用debug.Stackdebug.Stack是一个更简便的接口,直接返回格式化后的调用栈字符串,适合快速打印。例如:

    package main
    
    import (
        "debug/pe"
        "fmt"
    )
    
    func printCallStack() {
        fmt.Println(string(debug.Stack()))
    }
    
    func foo() {
        printCallStack()
    }
    
    func main() {
        foo()
    }
    

注意,这两个方法都适用于调试和开发阶段,但在生产环境中使用时需谨慎,以免产生过多日志或影响性能。

回到顶部