为了账号安全,请及时绑定邮箱和手机立即绑定

runtime.Callers 根据运行的位置打印不同的程序计数器

runtime.Callers 根据运行的位置打印不同的程序计数器

Go
汪汪一只猫 2022-07-04 16:51:47
我有下面的代码,它根据运行的位置打印不同的程序计数器值。代码:package mainimport (    "fmt"    "runtime")func foo() {    bar()}func bar() {    pcs := make([]uintptr, 10)    _ = runtime.Callers(0, pcs)    for _, pc := range pcs {        fmt.Printf("Value of pc %+v\n", runtime.FuncForPC(pc).Name())    }}func main() {    foo()}运行 usinggo run或编译的二进制文件时,它会打印 ( main.baris missing)Value of pc runtime.CallersValue of pc runtime.CallersValue of pc main.mainValue of pc main.fooValue of pc runtime.mainValue of pc runtime.goexit从 Visual Studio Code 运行代码时(仅在调试模式下,它工作正常)Value of pc runtime.CallersValue of pc main.barValue of pc main.fooValue of pc main.mainValue of pc runtime.mainValue of pc runtime.goexit在Playground中运行时,( foo, bar, 两者都缺失)Value of pc runtime.CallersValue of pc runtime.CallersValue of pc main.mainValue of pc main.mainValue of pc runtime.mainValue of pc runtime.goexit我正在使用一个框架(logrus),它依赖于 PC 的顺序来执行一些操作(记录文件名)。由于 PC 值会根据其运行位置不断变化,因此它在调试模式下工作,但在使用go run或编译的二进制文件运行时会失败。知道是什么导致 PC 加载不同吗?任何正在启动的配置或优化?
查看完整描述

1 回答

?
哆啦的时光机

TA贡献1779条经验 获得超6个赞

状态文件runtime.Callers():


要将这些 PC 转换为符号信息,例如函数名称和行号,请使用 CallersFrames。CallersFrames 考虑内联函数并将返回程序计数器调整为调用程序计数器。不鼓励直接迭代返回的 PC 切片,就像在任何返回的 PC 上使用 FuncForPC 一样,因为这些不能考虑内联或返回程序计数器调整。


Doc建议使用runtime.CallersFrames()从知道并解释函数内联的原始计数器获取函数信息,例如:


pcs := make([]uintptr, 10)

n := runtime.Callers(0, pcs)

pcs = pcs[:n]


frames := runtime.CallersFrames(pcs)

for {

    frame, more := frames.Next()

    if !more {

        break

    }

    fmt.Println("Function:", frame.Function)

}

无论您如何调用/运行它,这都应该输出(在Go Playground上尝试):


Function: runtime.Callers

Function: main.bar

Function: main.foo

Function: main.main

Function: runtime.main


查看完整回答
反对 回复 2022-07-04
  • 1 回答
  • 0 关注
  • 263 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信