Source file src/runtime/runtime_unix_test.go

     1  // Copyright 2013 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Only works on systems with syscall.Close.
     6  // We need a fast system call to provoke the race,
     7  // and Close(-1) is nearly universally fast.
     8  
     9  //go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || plan9
    10  
    11  package runtime_test
    12  
    13  import (
    14  	"runtime"
    15  	"sync"
    16  	"sync/atomic"
    17  	"syscall"
    18  	"testing"
    19  )
    20  
    21  func TestGoroutineProfile(t *testing.T) {
    22  	// GoroutineProfile used to use the wrong starting sp for
    23  	// goroutines coming out of system calls, causing possible
    24  	// crashes.
    25  	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(100))
    26  
    27  	var stop uint32
    28  	defer atomic.StoreUint32(&stop, 1) // in case of panic
    29  
    30  	var wg sync.WaitGroup
    31  	for i := 0; i < 4; i++ {
    32  		wg.Add(1)
    33  		go func() {
    34  			for atomic.LoadUint32(&stop) == 0 {
    35  				syscall.Close(-1)
    36  			}
    37  			wg.Done()
    38  		}()
    39  	}
    40  
    41  	max := 10000
    42  	if testing.Short() {
    43  		max = 100
    44  	}
    45  	stk := make([]runtime.StackRecord, 128)
    46  	for n := 0; n < max; n++ {
    47  		_, ok := runtime.GoroutineProfile(stk)
    48  		if !ok {
    49  			t.Fatalf("GoroutineProfile failed")
    50  		}
    51  	}
    52  
    53  	// If the program didn't crash, we passed.
    54  	atomic.StoreUint32(&stop, 1)
    55  	wg.Wait()
    56  }
    57  

View as plain text