]> Cypherpunks repositories - gostls13.git/commitdiff
runtime/pprof: test that stack barriers never appear in profile
authorAustin Clements <austin@google.com>
Wed, 18 Nov 2015 19:59:09 +0000 (14:59 -0500)
committerAustin Clements <austin@google.com>
Thu, 19 Nov 2015 16:35:43 +0000 (16:35 +0000)
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 <rsc@golang.org>
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/runtime/pprof/pprof_test.go

index 785d75a01e905cba5036560c00bd1544ce8c867c..2d8a187f83419d76a57a0bf19db42e58a7dde88d 100644 (file)
@@ -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,