59ea40d0f2
Patch by Svante Signell. Reviewed-on: https://go-review.googlesource.com/c/160823 From-SVN: r268460
57 lines
1.2 KiB
Go
57 lines
1.2 KiB
Go
// Copyright 2013 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// Only works on systems with syscall.Close.
|
|
// We need a fast system call to provoke the race,
|
|
// and Close(-1) is nearly universally fast.
|
|
|
|
// +build aix darwin dragonfly freebsd hurd linux netbsd openbsd plan9
|
|
|
|
package runtime_test
|
|
|
|
import (
|
|
"runtime"
|
|
"sync"
|
|
"sync/atomic"
|
|
"syscall"
|
|
"testing"
|
|
)
|
|
|
|
func TestGoroutineProfile(t *testing.T) {
|
|
// GoroutineProfile used to use the wrong starting sp for
|
|
// goroutines coming out of system calls, causing possible
|
|
// crashes.
|
|
defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(100))
|
|
|
|
var stop uint32
|
|
defer atomic.StoreUint32(&stop, 1) // in case of panic
|
|
|
|
var wg sync.WaitGroup
|
|
for i := 0; i < 4; i++ {
|
|
wg.Add(1)
|
|
go func() {
|
|
for atomic.LoadUint32(&stop) == 0 {
|
|
syscall.Close(-1)
|
|
}
|
|
wg.Done()
|
|
}()
|
|
}
|
|
|
|
max := 10000
|
|
if testing.Short() {
|
|
max = 100
|
|
}
|
|
stk := make([]runtime.StackRecord, 128)
|
|
for n := 0; n < max; n++ {
|
|
_, ok := runtime.GoroutineProfile(stk)
|
|
if !ok {
|
|
t.Fatalf("GoroutineProfile failed")
|
|
}
|
|
}
|
|
|
|
// If the program didn't crash, we passed.
|
|
atomic.StoreUint32(&stop, 1)
|
|
wg.Wait()
|
|
}
|