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 "sync/atomic" 19 "testing" 20 21 "./issue9400" 22 ) 23 24 func test9400(t *testing.T) { 25 // We synchronize through a shared variable, so we need two procs 26 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(2)) 27 28 // Start signaller 29 atomic.StoreInt32(&issue9400.Baton, 0) 30 go func() { 31 // Wait for RewindAndSetgid 32 for atomic.LoadInt32(&issue9400.Baton) == 0 { 33 runtime.Gosched() 34 } 35 // Broadcast SIGSETXID 36 runtime.LockOSThread() 37 C.setgid(0) 38 // Indicate that signalling is done 39 atomic.StoreInt32(&issue9400.Baton, 0) 40 }() 41 42 // Grow the stack and put down a test pattern 43 const pattern = 0x123456789abcdef 44 var big [1024]uint64 // len must match assmebly 45 for i := range big { 46 big[i] = pattern 47 } 48 49 // Temporarily rewind the stack and trigger SIGSETXID 50 issue9400.RewindAndSetgid() 51 52 // Check test pattern 53 for i := range big { 54 if big[i] != pattern { 55 t.Fatalf("entry %d of test pattern is wrong; %#x != %#x", i, big[i], uint64(pattern)) 56 } 57 } 58 } 59