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.
7 // Issue 18146: pthread_create failure during syscall.Exec.
24 func test18146(t
*testing
.T
) {
25 if runtime
.GOOS
== "darwin" {
26 t
.Skipf("skipping flaky test on %s; see golang.org/issue/18202", runtime
.GOOS
)
29 if runtime
.GOARCH
== "mips" || runtime
.GOARCH
== "mips64" {
30 t
.Skipf("skipping on %s", runtime
.GOARCH
)
40 // Restrict the number of attempts based on RLIMIT_NPROC.
41 // Tediously, RLIMIT_NPROC was left out of the syscall package,
42 // probably because it is not in POSIX.1, so we define it here.
43 // It is not defined on Solaris.
51 case "darwin", "dragonfly", "freebsd", "netbsd", "openbsd":
57 var rlim syscall
.Rlimit
58 if syscall
.Getrlimit(nproc
, &rlim
) == nil {
59 max
:= int(rlim
.Cur
) / (threads
+ 5)
61 t
.Logf("lowering attempts from %d to %d for RLIMIT_NPROC", attempts
, max
)
67 if os
.Getenv("test18146") == "exec" {
69 for n
:= threads
; n
> 0; n
-- {
72 _
= md5
.Sum([]byte("Hello, !"))
76 runtime
.GOMAXPROCS(threads
)
77 argv
:= append(os
.Args
, "-test.run=NoSuchTestExists")
78 if err
:= syscall
.Exec(os
.Args
[0], argv
, os
.Environ()); err
!= nil {
85 for _
, cmd
:= range cmds
{
90 args
:= append(append([]string(nil), os
.Args
[1:]...), "-test.run=Test18146")
91 for n
:= attempts
; n
> 0; n
-- {
92 cmd
:= exec
.Command(os
.Args
[0], args
...)
93 cmd
.Env
= append(os
.Environ(), "test18146=exec")
94 buf
:= bytes
.NewBuffer(nil)
97 if err
:= cmd
.Start(); err
!= nil {
98 // We are starting so many processes that on
99 // some systems (problem seen on Darwin,
100 // Dragonfly, OpenBSD) the fork call will fail
102 if pe
, ok
:= err
.(*os
.PathError
); ok
{
105 if se
, ok
:= err
.(syscall
.Errno
); ok
&& (se
== syscall
.EAGAIN || se
== syscall
.EMFILE
) {
106 time
.Sleep(time
.Millisecond
)
113 cmds
= append(cmds
, cmd
)
117 for _
, cmd
:= range cmds
{
123 t
.Errorf("syscall.Exec failed: %v\n%s", err
, cmd
.Stdout
)
128 t
.Logf("Failed %v of %v attempts.", failures
, len(cmds
))