github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/runtime/example_test.go (about)

     1  // Copyright 2017 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package runtime_test
     6  
     7  import (
     8  	"github.com/shogo82148/std/fmt"
     9  	"github.com/shogo82148/std/runtime"
    10  	"github.com/shogo82148/std/strings"
    11  )
    12  
    13  func ExampleFrames() {
    14  	c := func() {
    15  		// runtime.Callersを含めて最大10個のPCを要求します。
    16  		pc := make([]uintptr, 10)
    17  		n := runtime.Callers(0, pc)
    18  		if n == 0 {
    19  			// PC(プログラムカウンタ)が利用できません。これは、runtime.Callersの最初の引数が大きい場合に発生する可能性があります。
    20  			//
    21  			// frames.Next以下で返されるはずのゼロのフレームを処理しないため、ここでリターンします。
    22  			return
    23  		}
    24  
    25  		pc = pc[:n] // runtime.CallersFramesには有効なプログラムカウンタ(pcs)のみを渡してください。
    26  		frames := runtime.CallersFrames(pc)
    27  
    28  		// フレームを取得するためのループ。
    29  		// 固定数のPCが無限のフレームに拡張できます。
    30  		for {
    31  			frame, more := frames.Next()
    32  
    33  			// このフレームを処理します。
    34  			//
    35  			// この例の出力を安定させるために
    36  			// テストパッケージに変更があっても
    37  			// runtimeパッケージを抜けるとアンワインドを停止します。
    38  			if !strings.Contains(frame.File, "runtime/") {
    39  				break
    40  			}
    41  			fmt.Printf("- more:%v | %s\n", more, frame.Function)
    42  
    43  			// このフレームの処理後にさらにフレームがあるかどうかを確認します。
    44  			if !more {
    45  				break
    46  			}
    47  		}
    48  	}
    49  
    50  	b := func() { c() }
    51  	a := func() { b() }
    52  
    53  	a()
    54  	// Output:
    55  	// - more:true | runtime.Callers
    56  	// - more:true | runtime_test.ExampleFrames.func1
    57  	// - more:true | runtime_test.ExampleFrames.func2
    58  	// - more:true | runtime_test.ExampleFrames.func3
    59  	// - more:true | runtime_test.ExampleFrames
    60  }