From 9a7893550c506c2fb69711334ace1ae17176ccf4 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Wed, 18 Nov 2015 14:59:09 -0500 Subject: [PATCH] runtime/pprof: test that stack barriers never appear in profile This adds a test that runs CPU profiling with a high load of stack barriers and stack barrier insertion/removal operations and checks that both 1) the runtime doesn't crash and 2) stackBarrier itself never appears in a profile. Prior to the fix for gentraceback starting in the middle of stackBarrier, condition 2 often failed. Change-Id: Ic28860448859029779844c4bf3bb28ca84611e2c Reviewed-on: https://go-review.googlesource.com/17037 Reviewed-by: Russ Cox Run-TryBot: Austin Clements TryBot-Result: Gobot Gobot --- src/runtime/pprof/pprof_test.go | 45 +++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/runtime/pprof/pprof_test.go b/src/runtime/pprof/pprof_test.go index 785d75a01e9..2d8a187f834 100644 --- a/src/runtime/pprof/pprof_test.go +++ b/src/runtime/pprof/pprof_test.go @@ -160,6 +160,10 @@ func testCPUProfile(t *testing.T, need []string, f func()) { have[i] += count } } + if strings.Contains(f.Name(), "stackBarrier") { + // The runtime should have unwound this. + t.Fatalf("profile includes stackBarrier") + } } }) t.Logf("total %d CPU profile samples collected", samples) @@ -324,6 +328,47 @@ func TestMathBigDivide(t *testing.T) { }) } +func TestStackBarrierProfiling(t *testing.T) { + if !strings.Contains(os.Getenv("GODEBUG"), "gcstackbarrierall=1") { + // Re-execute this test with constant GC and stack + // barriers at every frame. + cmd := exec.Command(os.Args[0], "-test.run=TestStackBarrierProfiling") + cmd.Env = append([]string{"GODEBUG=gcstackbarrierall=1", "GOGC=1"}, os.Environ()...) + if out, err := cmd.CombinedOutput(); err != nil { + t.Fatalf("subprocess failed with %v:\n%s", err, out) + } + return + } + + testCPUProfile(t, nil, func() { + // This is long enough that we're likely to get one or + // two samples in stackBarrier. + duration := 5 * time.Second + if testing.Short() { + duration = 1 * time.Second + } + t := time.After(duration) + for { + deepStack(1000) + select { + case <-t: + return + default: + } + } + }) +} + +var x []byte + +func deepStack(depth int) int { + if depth == 0 { + return 0 + } + x = make([]byte, 1024) + return deepStack(depth-1) + 1 +} + // Operating systems that are expected to fail the tests. See issue 6047. var badOS = map[string]bool{ "darwin": true,