Mercurial > hg > CbC > CbC_gcc
comparison libgo/misc/cgo/test/issue18146.go @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
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. | |
4 | |
5 // +build !windows | |
6 | |
7 // Issue 18146: pthread_create failure during syscall.Exec. | |
8 | |
9 package cgotest | |
10 | |
11 import "C" | |
12 | |
13 import ( | |
14 "bytes" | |
15 "crypto/md5" | |
16 "os" | |
17 "os/exec" | |
18 "runtime" | |
19 "syscall" | |
20 "testing" | |
21 "time" | |
22 ) | |
23 | |
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) | |
27 } | |
28 | |
29 if runtime.GOARCH == "mips" || runtime.GOARCH == "mips64" { | |
30 t.Skipf("skipping on %s", runtime.GOARCH) | |
31 } | |
32 | |
33 attempts := 1000 | |
34 threads := 4 | |
35 | |
36 if testing.Short() { | |
37 attempts = 100 | |
38 } | |
39 | |
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. | |
44 var nproc int | |
45 setNproc := true | |
46 switch runtime.GOOS { | |
47 default: | |
48 setNproc = false | |
49 case "linux": | |
50 nproc = 6 | |
51 case "darwin", "dragonfly", "freebsd", "netbsd", "openbsd": | |
52 nproc = 7 | |
53 case "aix": | |
54 nproc = 9 | |
55 } | |
56 if setNproc { | |
57 var rlim syscall.Rlimit | |
58 if syscall.Getrlimit(nproc, &rlim) == nil { | |
59 max := int(rlim.Cur) / (threads + 5) | |
60 if attempts > max { | |
61 t.Logf("lowering attempts from %d to %d for RLIMIT_NPROC", attempts, max) | |
62 attempts = max | |
63 } | |
64 } | |
65 } | |
66 | |
67 if os.Getenv("test18146") == "exec" { | |
68 runtime.GOMAXPROCS(1) | |
69 for n := threads; n > 0; n-- { | |
70 go func() { | |
71 for { | |
72 _ = md5.Sum([]byte("Hello, !")) | |
73 } | |
74 }() | |
75 } | |
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 { | |
79 t.Fatal(err) | |
80 } | |
81 } | |
82 | |
83 var cmds []*exec.Cmd | |
84 defer func() { | |
85 for _, cmd := range cmds { | |
86 cmd.Process.Kill() | |
87 } | |
88 }() | |
89 | |
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) | |
95 cmd.Stdout = buf | |
96 cmd.Stderr = buf | |
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 | |
101 // with EAGAIN. | |
102 if pe, ok := err.(*os.PathError); ok { | |
103 err = pe.Err | |
104 } | |
105 if se, ok := err.(syscall.Errno); ok && (se == syscall.EAGAIN || se == syscall.EMFILE) { | |
106 time.Sleep(time.Millisecond) | |
107 continue | |
108 } | |
109 | |
110 t.Error(err) | |
111 return | |
112 } | |
113 cmds = append(cmds, cmd) | |
114 } | |
115 | |
116 failures := 0 | |
117 for _, cmd := range cmds { | |
118 err := cmd.Wait() | |
119 if err == nil { | |
120 continue | |
121 } | |
122 | |
123 t.Errorf("syscall.Exec failed: %v\n%s", err, cmd.Stdout) | |
124 failures++ | |
125 } | |
126 | |
127 if failures > 0 { | |
128 t.Logf("Failed %v of %v attempts.", failures, len(cmds)) | |
129 } | |
130 } |