mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			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 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()
 | |
| }
 |