From 46ecac99fb83c3e9ea0d817839c7136ef74d3d10 Mon Sep 17 00:00:00 2001 From: David Lazar Date: Tue, 18 Apr 2017 15:12:54 -0400 Subject: [PATCH] io: correctly compute call depth in test TestMultiReaderFlatten determines the call depth by counting PCs returned by runtime.Callers. With inlining, this is incorrect because a PC can represent multiple calls. Furthermore, runtime.Callers might return an additional "skip" PC, which does not represent a real call. This modifies the test to use CallersFrames to determine the call depth. Now the test passes with -l=4. Change-Id: I284f3b1e0b2d194bd08c230c616914503e5a370d Reviewed-on: https://go-review.googlesource.com/40990 Run-TryBot: David Lazar Reviewed-by: Austin Clements TryBot-Result: Gobot Gobot --- src/io/multi_test.go | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/io/multi_test.go b/src/io/multi_test.go index 710776ad24..0a7eb43032 100644 --- a/src/io/multi_test.go +++ b/src/io/multi_test.go @@ -175,13 +175,26 @@ func (f readerFunc) Read(p []byte) (int, error) { return f(p) } +// callDepth returns the logical call depth for the given PCs. +func callDepth(callers []uintptr) (depth int) { + frames := runtime.CallersFrames(callers) + more := true + for more { + _, more = frames.Next() + depth++ + } + return +} + // Test that MultiReader properly flattens chained multiReaders when Read is called func TestMultiReaderFlatten(t *testing.T) { pc := make([]uintptr, 1000) // 1000 should fit the full stack - var myDepth = runtime.Callers(0, pc) + n := runtime.Callers(0, pc) + var myDepth = callDepth(pc[:n]) var readDepth int // will contain the depth from which fakeReader.Read was called var r Reader = MultiReader(readerFunc(func(p []byte) (int, error) { - readDepth = runtime.Callers(1, pc) + n := runtime.Callers(1, pc) + readDepth = callDepth(pc[:n]) return 0, errors.New("irrelevant") })) -- 2.48.1