Source file misc/cgo/test/testdata/issue9400_linux.go
1 // Copyright 2014 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 // Test that SIGSETXID runs on signal stack, since it's likely to 6 // overflow if it runs on the Go stack. 7 8 package cgotest 9 10 /* 11 #include <sys/types.h> 12 #include <unistd.h> 13 */ 14 import "C" 15 16 import ( 17 "runtime" 18 "runtime/debug" 19 "sync/atomic" 20 "testing" 21 22 "cgotest/issue9400" 23 ) 24 25 func test9400(t *testing.T) { 26 // We synchronize through a shared variable, so we need two procs 27 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(2)) 28 29 // Start signaller 30 atomic.StoreInt32(&issue9400.Baton, 0) 31 go func() { 32 // Wait for RewindAndSetgid 33 for atomic.LoadInt32(&issue9400.Baton) == 0 { 34 runtime.Gosched() 35 } 36 // Broadcast SIGSETXID 37 runtime.LockOSThread() 38 C.setgid(0) 39 // Indicate that signalling is done 40 atomic.StoreInt32(&issue9400.Baton, 0) 41 }() 42 43 // Grow the stack and put down a test pattern 44 const pattern = 0x123456789abcdef 45 var big [1024]uint64 // len must match assembly 46 for i := range big { 47 big[i] = pattern 48 } 49 50 // Disable GC for the duration of the test. 51 // This avoids a potential GC deadlock when spinning in uninterruptable ASM below #49695. 52 defer debug.SetGCPercent(debug.SetGCPercent(-1)) 53 // SetGCPercent waits until the mark phase is over, but the runtime 54 // also preempts at the start of the sweep phase, so make sure that's 55 // done too. See #49695. 56 runtime.GC() 57 58 // Temporarily rewind the stack and trigger SIGSETXID 59 issue9400.RewindAndSetgid() 60 61 // Check test pattern 62 for i := range big { 63 if big[i] != pattern { 64 t.Fatalf("entry %d of test pattern is wrong; %#x != %#x", i, big[i], uint64(pattern)) 65 } 66 } 67 } 68