| // 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 |
| } |