Goのruntime.Callerで返されるpcはスタックではない
Goの runtime には Caller や Callers 関数が用意されていて、現在実行中のプログラムカウンタを返してくれる。ただしこれはコードの位置なので、コールスタックの値ではない。また、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 4720117Entry: 0 4720064PC: 1 4720117Entry: 1 4720064PC: 2 4720117Entry: 2 4720064PC: 3 4720823Entry: 3 4720800