I have this below code that prints different program counter values depending on where its run from.
Code:
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()
}
- When running using
go runor the compiled binary, it prints (main.baris missing)
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
- When running the code from Visual Studio Code (Only in debug mode, it works fine)
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
- When running in Playground, (
foo,bar, both are missing)
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
I'm using a framework (logrus) which relies on the PCs order to perform some operation (logging the filename).
Since the PC values keeps changing depending on where its run from, it works in Debug Mode but fails when running using go run or the compiled binary.
Any idea what could be causing the PCs to load differently? Any config or optimization that's kicking in?
Documentation of
runtime.Callers()states:Doc suggests to use
runtime.CallersFrames()to obtain function information from the raw counters which knows about and accounts for function inlining, for example:This should output regardless of how you call / run it (try it on the Go Playground):