1 // Copyright 2016 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.
5 //go:build cgo && !windows
7 // Issue 18146: pthread_create failure during syscall.Exec.
22 func test18146(t *testing.T) {
24 t.Skip("skipping in short mode")
27 if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
28 t.Skipf("skipping flaky test on %s; see golang.org/issue/18202", runtime.GOOS)
31 if runtime.GOARCH == "mips" || runtime.GOARCH == "mips64" {
32 t.Skipf("skipping on %s", runtime.GOARCH)
38 // Restrict the number of attempts based on RLIMIT_NPROC.
39 // Tediously, RLIMIT_NPROC was left out of the syscall package,
40 // probably because it is not in POSIX.1, so we define it here.
41 // It is not defined on Solaris.
51 case "darwin", "dragonfly", "freebsd", "netbsd", "openbsd":
55 var rlim syscall.Rlimit
56 if syscall.Getrlimit(nproc, &rlim) == nil {
57 max := int(rlim.Cur) / (threads + 5)
59 t.Logf("lowering attempts from %d to %d for RLIMIT_NPROC", attempts, max)
65 if os.Getenv("test18146") == "exec" {
67 for n := threads; n > 0; n-- {
70 _ = md5.Sum([]byte("Hello, !"))
74 runtime.GOMAXPROCS(threads)
75 argv := append(os.Args, "-test.run=NoSuchTestExists")
76 if err := syscall.Exec(os.Args[0], argv, os.Environ()); err != nil {
83 for _, cmd := range cmds {
88 args := append(append([]string(nil), os.Args[1:]...), "-test.run=Test18146")
89 for n := attempts; n > 0; n-- {
90 cmd := exec.Command(os.Args[0], args...)
91 cmd.Env = append(os.Environ(), "test18146=exec")
92 buf := bytes.NewBuffer(nil)
95 if err := cmd.Start(); err != nil {
96 // We are starting so many processes that on
97 // some systems (problem seen on Darwin,
98 // Dragonfly, OpenBSD) the fork call will fail
100 if pe, ok := err.(*os.PathError); ok {
103 if se, ok := err.(syscall.Errno); ok && (se == syscall.EAGAIN || se == syscall.EMFILE) {
104 time.Sleep(time.Millisecond)
111 cmds = append(cmds, cmd)
115 for _, cmd := range cmds {
121 t.Errorf("syscall.Exec failed: %v\n%s", err, cmd.Stdout)
126 t.Logf("Failed %v of %v attempts.", failures, len(cmds))