]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: clarify Frames.Next documentation
authorMatthew Dempsky <mdempsky@google.com>
Fri, 18 Jun 2021 05:12:24 +0000 (22:12 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Fri, 18 Jun 2021 22:05:09 +0000 (22:05 +0000)
I wrote code that relied on this API, but I misunderstood the original
description of the "more" result. As a consequence, my code always
stopped one frame early.

This CL expands the documentation to be more explicit and specifically
call out my confusion (i.e., that the "more" result indicates whether
the *next* Next call will return a valid Frame, and not whether this
call did).

Change-Id: If135f8f8c05425073d45377c4179e4f79e6bd6ca
Reviewed-on: https://go-review.googlesource.com/c/go/+/329389
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Trust: Matthew Dempsky <mdempsky@google.com>

src/runtime/example_test.go
src/runtime/symtab.go

index e4912a51588991ce5743e5b01940c860f6de7713..dcb8f7798e290581eab6858bbcb348966b0cd810 100644 (file)
@@ -12,12 +12,15 @@ import (
 
 func ExampleFrames() {
        c := func() {
-               // Ask runtime.Callers for up to 10 pcs, including runtime.Callers itself.
+               // 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. Stop now.
-                       // This can happen if the first argument to runtime.Callers is large.
+                       // 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
                }
 
@@ -25,9 +28,12 @@ func ExampleFrames() {
                frames := runtime.CallersFrames(pc)
 
                // Loop to get frames.
-               // A fixed number of pcs can expand to an indefinite number of 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.
@@ -35,6 +41,8 @@ func ExampleFrames() {
                                break
                        }
                        fmt.Printf("- more:%v | %s\n", more, frame.Function)
+
+                       // Check whether there are more frames to process after this one.
                        if !more {
                                break
                        }
index 6b535dfcbfc324448a0701dafaa75bd79543cbe4..999300a58ec3404baf8ec991b522ffe942b096fe 100644 (file)
@@ -68,8 +68,15 @@ func CallersFrames(callers []uintptr) *Frames {
        return f
 }
 
-// Next returns frame information for the next caller.
-// If more is false, there are no more callers (the Frame value is valid).
+// Next returns a Frame representing the next call frame in the slice
+// of PC values. If it has already returned all call frames, Next
+// returns a zero Frame.
+//
+// The more result indicates whether the next call to Next will return
+// a valid Frame. It does not necessarily indicate whether this call
+// returned one.
+//
+// See the Frames example for idiomatic usage.
 func (ci *Frames) Next() (frame Frame, more bool) {
        for len(ci.frames) < 2 {
                // Find the next frame.