diff options
author | Ian Lance Taylor <iant@golang.org> | 2022-02-18 13:10:34 -0800 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2022-02-18 13:12:08 -0800 |
commit | 20a33efdf32bf0aedcb0c9813ddc7572bb1ab8c7 (patch) | |
tree | 94aec72c2092a11fa49f0b45da8e036f13416209 /libgo/go/syscall | |
parent | 1931cbad498e625b1e24452dcfffe02539b12224 (diff) | |
download | gcc-20a33efdf32bf0aedcb0c9813ddc7572bb1ab8c7.tar.gz |
libgo: update to Go1.18rc1 release
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/386594
Diffstat (limited to 'libgo/go/syscall')
-rw-r--r-- | libgo/go/syscall/syscall_linux_test.go | 71 | ||||
-rw-r--r-- | libgo/go/syscall/syscall_unix_test.go | 21 |
2 files changed, 75 insertions, 17 deletions
diff --git a/libgo/go/syscall/syscall_linux_test.go b/libgo/go/syscall/syscall_linux_test.go index 6be48e24dc7..3169cdda556 100644 --- a/libgo/go/syscall/syscall_linux_test.go +++ b/libgo/go/syscall/syscall_linux_test.go @@ -15,6 +15,7 @@ import ( "sort" "strconv" "strings" + "sync" "syscall" "testing" "unsafe" @@ -569,3 +570,73 @@ func TestSetuidEtc(t *testing.T) { } } } + +// TestAllThreadsSyscallError verifies that errors are properly returned when +// the syscall fails on the original thread. +func TestAllThreadsSyscallError(t *testing.T) { + // SYS_CAPGET takes pointers as the first two arguments. Since we pass + // 0, we expect to get EFAULT back. + r1, r2, err := syscall.AllThreadsSyscall(syscall.SYS_CAPGET, 0, 0, 0) + if err == syscall.ENOTSUP { + t.Skip("AllThreadsSyscall disabled with cgo") + } + if err != syscall.EFAULT { + t.Errorf("AllThreadSyscall(SYS_CAPGET) got %d, %d, %v, want err %v", r1, r2, err, syscall.EFAULT) + } +} + +// TestAllThreadsSyscallBlockedSyscall confirms that AllThreadsSyscall +// can interrupt threads in long-running system calls. This test will +// deadlock if this doesn't work correctly. +func TestAllThreadsSyscallBlockedSyscall(t *testing.T) { + if _, _, err := syscall.AllThreadsSyscall(syscall.SYS_PRCTL, PR_SET_KEEPCAPS, 0, 0); err == syscall.ENOTSUP { + t.Skip("AllThreadsSyscall disabled with cgo") + } + + rd, wr, err := os.Pipe() + if err != nil { + t.Fatalf("unable to obtain a pipe: %v", err) + } + + // Perform a blocking read on the pipe. + var wg sync.WaitGroup + ready := make(chan bool) + wg.Add(1) + go func() { + data := make([]byte, 1) + + // To narrow the window we have to wait for this + // goroutine to block in read, synchronize just before + // calling read. + ready <- true + + // We use syscall.Read directly to avoid the poller. + // This will return when the write side is closed. + n, err := syscall.Read(int(rd.Fd()), data) + if !(n == 0 && err == nil) { + t.Errorf("expected read to return 0, got %d, %s", n, err) + } + + // Clean up rd and also ensure rd stays reachable so + // it doesn't get closed by GC. + rd.Close() + wg.Done() + }() + <-ready + + // Loop here to give the goroutine more time to block in read. + // Generally this will trigger on the first iteration anyway. + pid := syscall.Getpid() + for i := 0; i < 100; i++ { + if id, _, e := syscall.AllThreadsSyscall(syscall.SYS_GETPID, 0, 0, 0); e != 0 { + t.Errorf("[%d] getpid failed: %v", i, e) + } else if int(id) != pid { + t.Errorf("[%d] getpid got=%d, want=%d", i, id, pid) + } + // Provide an explicit opportunity for this goroutine + // to change Ms. + runtime.Gosched() + } + wr.Close() + wg.Wait() +} diff --git a/libgo/go/syscall/syscall_unix_test.go b/libgo/go/syscall/syscall_unix_test.go index 205c6003261..8bfbc934035 100644 --- a/libgo/go/syscall/syscall_unix_test.go +++ b/libgo/go/syscall/syscall_unix_test.go @@ -330,8 +330,7 @@ func TestUnixRightsRoundtrip(t *testing.T) { func TestRlimit(t *testing.T) { var rlimit, zero syscall.Rlimit - err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rlimit) - if err != nil { + if err := syscall.Getrlimit(syscall.RLIMIT_CPU, &rlimit); err != nil { t.Fatalf("Getrlimit: save failed: %v", err) } if zero == rlimit { @@ -339,31 +338,19 @@ func TestRlimit(t *testing.T) { } set := rlimit set.Cur = set.Max - 1 - if (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && set.Cur > 4096 { - // rlim_min for RLIMIT_NOFILE should be equal to - // or lower than kern.maxfilesperproc, which on - // some machines are 4096. See #40564. - set.Cur = 4096 - } - err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &set) - if err != nil { + if err := syscall.Setrlimit(syscall.RLIMIT_CPU, &set); err != nil { t.Fatalf("Setrlimit: set failed: %#v %v", set, err) } var get syscall.Rlimit - err = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &get) - if err != nil { + if err := syscall.Getrlimit(syscall.RLIMIT_CPU, &get); err != nil { t.Fatalf("Getrlimit: get failed: %v", err) } set = rlimit set.Cur = set.Max - 1 - if (runtime.GOOS == "darwin" || runtime.GOOS == "ios") && set.Cur > 4096 { - set.Cur = 4096 - } if set != get { t.Fatalf("Rlimit: change failed: wanted %#v got %#v", set, get) } - err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rlimit) - if err != nil { + if err := syscall.Setrlimit(syscall.RLIMIT_CPU, &rlimit); err != nil { t.Fatalf("Setrlimit: restore failed: %#v %v", rlimit, err) } } |