如何解决运行时调用者根据其运行位置打印不同的程序计数器
代码:
package main
import (
"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()
}
- 使用
go run
或已编译的二进制文件运行时,它会打印(缺少main.bar
)
Value of pc runtime.Callers
Value of pc runtime.Callers
Value of pc main.main
Value of pc main.foo
Value of pc runtime.main
Value of pc runtime.goexit
Value of pc runtime.Callers
Value of pc main.bar
Value of pc main.foo
Value of pc main.main
Value of pc runtime.main
Value of pc runtime.goexit
- 在Playground,(
foo
,bar
中运行时,两者均缺失)
Value of pc runtime.Callers
Value of pc runtime.Callers
Value of pc main.main
Value of pc main.main
Value of pc runtime.main
Value of pc runtime.goexit
我正在使用一个框架(日志),该框架依赖于PC的命令来执行某些操作(记录文件名)。
由于PC值根据其运行位置而不断变化,因此它可以在调试模式下运行,但在使用go run
或编译后的二进制文件运行时会失败。
任何想法都可能导致PC负载不同吗?有任何配置或优化吗?
解决方法
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
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。