|  | // Copyright 2017 The Go Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style | 
|  | // license that can be found in the LICENSE file. | 
|  |  | 
|  | package runtime_test | 
|  |  | 
|  | import ( | 
|  | "fmt" | 
|  | "runtime" | 
|  | "strings" | 
|  | ) | 
|  |  | 
|  | func ExampleFrames() { | 
|  | c := func() { | 
|  | // Ask runtime.Callers for up to 10 PCs, including runtime.Callers itself. | 
|  | pc := make([]uintptr, 10) | 
|  | n := runtime.Callers(0, pc) | 
|  | if n == 0 { | 
|  | // No PCs available. This can happen if the first argument to | 
|  | // runtime.Callers is large. | 
|  | // | 
|  | // Return now to avoid processing the zero Frame that would | 
|  | // otherwise be returned by frames.Next below. | 
|  | return | 
|  | } | 
|  |  | 
|  | pc = pc[:n] // pass only valid pcs to runtime.CallersFrames | 
|  | frames := runtime.CallersFrames(pc) | 
|  |  | 
|  | // Loop to get frames. | 
|  | // A fixed number of PCs can expand to an indefinite number of Frames. | 
|  | for { | 
|  | frame, more := frames.Next() | 
|  |  | 
|  | // Process this frame. | 
|  | // | 
|  | // To keep this example's output stable | 
|  | // even if there are changes in the testing package, | 
|  | // stop unwinding when we leave package runtime. | 
|  | if !strings.Contains(frame.File, "runtime/") { | 
|  | break | 
|  | } | 
|  | fmt.Printf("- more:%v | %s\n", more, frame.Function) | 
|  |  | 
|  | // Check whether there are more frames to process after this one. | 
|  | if !more { | 
|  | break | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | b := func() { c() } | 
|  | a := func() { b() } | 
|  |  | 
|  | a() | 
|  | // Output: | 
|  | // - more:true | runtime.Callers | 
|  | // - more:true | runtime_test.ExampleFrames.func1 | 
|  | // - more:true | runtime_test.ExampleFrames.func2 | 
|  | // - more:true | runtime_test.ExampleFrames.func3 | 
|  | // - more:true | runtime_test.ExampleFrames | 
|  | } |