issue9400_linux.go 1.7 KB

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