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