}
buf := make([]byte, 1<<20)
- buf = buf[:runtime.Stack(buf, true)]
- n := runtime.NumGoroutine()
+ // Try up to 10 times for a match before giving up.
+ // This is a fundamentally racy check but it's important
+ // to notice if NumGoroutine and Stack are _always_ out of sync.
+ for i := 0; ; i++ {
+ // Give goroutines about to exit a chance to exit.
+ // The NumGoroutine and Stack below need to see
+ // the same state of the world, so anything we can do
+ // to keep it quiet is good.
+ runtime.Gosched()
+
+ n := runtime.NumGoroutine()
+ buf = buf[:runtime.Stack(buf, true)]
- if nstk := strings.Count(string(buf), "goroutine "); n != nstk {
- t.Fatalf("NumGoroutine=%d, but found %d goroutines in stack dump: %s", n, nstk, buf)
+ nstk := strings.Count(string(buf), "goroutine ")
+ if n == nstk {
+ break
+ }
+ if i >= 10 {
+ t.Fatalf("NumGoroutine=%d, but found %d goroutines in stack dump: %s", n, nstk, buf)
+ }
}
}