Skip to content

Goのruntime.Callerで返されるpcはスタックではない

Goの runtime には CallerCallers 関数が用意されていて、現在実行中のプログラムカウンタを返してくれる。ただしこれはコードの位置なので、コールスタックの値ではない。また、runtime.Frame.Entry も関数コードのエントリアドレスであって呼び出し履歴の影響は受けない。

func rec(n int) {
if n > 0 {
rec(n - 1)
}
pc, _, _, _ := runtime.Caller(1)
fmt.Println("PC:", n, pc)
frames := runtime.CallersFrames([]uintptr{pc})
frame, _ := frames.Next()
fmt.Println("Entry:", n, frame.Entry)
}
func main() {
rec(3)
}

このとき、結果は次のようになる。スタックの影響を受けないことが分かる。

PC: 0 4720117
Entry: 0 4720064
PC: 1 4720117
Entry: 1 4720064
PC: 2 4720117
Entry: 2 4720064
PC: 3 4720823
Entry: 3 4720800