Home | History | Annotate | Download | only in test
      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