1
2
3
4
5 package main
6
7 import (
8 "os"
9 "runtime"
10 "runtime/pprof"
11 "sync"
12 )
13
14
15
16
17
18
19
20
21
22 func init() {
23 register("NilRecv", NilRecv)
24 register("NilSend", NilSend)
25 register("SelectNoCases", SelectNoCases)
26 register("SelectNoCasesMain", SelectNoCasesMain)
27 register("ChanRecv", ChanRecv)
28 register("ChanSend", ChanSend)
29 register("Select", Select)
30 register("WaitGroup", WaitGroup)
31 register("MutexStack", MutexStack)
32 register("MutexHeap", MutexHeap)
33 register("RWMutexRLock", RWMutexRLock)
34 register("RWMutexLock", RWMutexLock)
35 register("Cond", Cond)
36 register("Mixed", Mixed)
37 register("NoLeakGlobal", NoLeakGlobal)
38 }
39
40 func NilRecv() {
41 prof := pprof.Lookup("goroutineleak")
42 go func() {
43 var c chan int
44 <-c
45 panic("should not be reached")
46 }()
47
48 for i := 0; i < yieldCount; i++ {
49 runtime.Gosched()
50 }
51 prof.WriteTo(os.Stdout, 2)
52 }
53
54 func NilSend() {
55 prof := pprof.Lookup("goroutineleak")
56 go func() {
57 var c chan int
58 c <- 0
59 panic("should not be reached")
60 }()
61
62 for i := 0; i < yieldCount; i++ {
63 runtime.Gosched()
64 }
65 prof.WriteTo(os.Stdout, 2)
66 }
67
68 func ChanRecv() {
69 prof := pprof.Lookup("goroutineleak")
70 go func() {
71 <-make(chan int)
72 panic("should not be reached")
73 }()
74
75 for i := 0; i < yieldCount; i++ {
76 runtime.Gosched()
77 }
78 prof.WriteTo(os.Stdout, 2)
79 }
80
81 func SelectNoCases() {
82 prof := pprof.Lookup("goroutineleak")
83 go func() {
84 select {}
85 panic("should not be reached")
86 }()
87
88 for i := 0; i < yieldCount; i++ {
89 runtime.Gosched()
90 }
91 prof.WriteTo(os.Stdout, 2)
92 }
93
94 func SelectNoCasesMain() {
95 prof := pprof.Lookup("goroutineleak")
96 ch := make(chan int)
97 go func() {
98
99 <-ch
100 }()
101 go func() {
102 for i := 0; i < yieldCount; i++ {
103 runtime.Gosched()
104 }
105
106
107 prof.WriteTo(os.Stdout, 2)
108
109 os.Exit(0)
110 }()
111
112 select {}
113 }
114
115 func ChanSend() {
116 prof := pprof.Lookup("goroutineleak")
117 go func() {
118 make(chan int) <- 0
119 panic("should not be reached")
120 }()
121
122 for i := 0; i < yieldCount; i++ {
123 runtime.Gosched()
124 }
125 prof.WriteTo(os.Stdout, 2)
126 }
127
128 func Select() {
129 prof := pprof.Lookup("goroutineleak")
130 go func() {
131 select {
132 case make(chan int) <- 0:
133 case <-make(chan int):
134 }
135 panic("should not be reached")
136 }()
137
138 for i := 0; i < yieldCount; i++ {
139 runtime.Gosched()
140 }
141 prof.WriteTo(os.Stdout, 2)
142 }
143
144 func WaitGroup() {
145 prof := pprof.Lookup("goroutineleak")
146 go func() {
147 var wg sync.WaitGroup
148 wg.Add(1)
149 wg.Wait()
150 panic("should not be reached")
151 }()
152
153 for i := 0; i < yieldCount; i++ {
154 runtime.Gosched()
155 }
156 prof.WriteTo(os.Stdout, 2)
157 }
158
159 func MutexStack() {
160 prof := pprof.Lookup("goroutineleak")
161 for i := 0; i < 1000; i++ {
162 go func() {
163 var mu sync.Mutex
164 mu.Lock()
165 mu.Lock()
166 panic("should not be reached")
167 }()
168 }
169
170 for i := 0; i < yieldCount; i++ {
171 runtime.Gosched()
172 }
173 prof.WriteTo(os.Stdout, 2)
174 }
175
176 func MutexHeap() {
177 prof := pprof.Lookup("goroutineleak")
178 for i := 0; i < 1000; i++ {
179 go func() {
180 mu := &sync.Mutex{}
181 go func() {
182 mu.Lock()
183 mu.Lock()
184 panic("should not be reached")
185 }()
186 }()
187 }
188
189 for i := 0; i < yieldCount; i++ {
190 runtime.Gosched()
191 }
192 prof.WriteTo(os.Stdout, 2)
193 }
194
195 func RWMutexRLock() {
196 prof := pprof.Lookup("goroutineleak")
197 go func() {
198 mu := &sync.RWMutex{}
199 mu.Lock()
200 mu.RLock()
201 panic("should not be reached")
202 }()
203
204 for i := 0; i < yieldCount; i++ {
205 runtime.Gosched()
206 }
207 prof.WriteTo(os.Stdout, 2)
208 }
209
210 func RWMutexLock() {
211 prof := pprof.Lookup("goroutineleak")
212 go func() {
213 mu := &sync.RWMutex{}
214 mu.Lock()
215 mu.Lock()
216 panic("should not be reached")
217 }()
218
219 for i := 0; i < yieldCount; i++ {
220 runtime.Gosched()
221 }
222 prof.WriteTo(os.Stdout, 2)
223 }
224
225 func Cond() {
226 prof := pprof.Lookup("goroutineleak")
227 go func() {
228 cond := sync.NewCond(&sync.Mutex{})
229 cond.L.Lock()
230 cond.Wait()
231 panic("should not be reached")
232 }()
233
234 for i := 0; i < yieldCount; i++ {
235 runtime.Gosched()
236 }
237 prof.WriteTo(os.Stdout, 2)
238 }
239
240 func Mixed() {
241 prof := pprof.Lookup("goroutineleak")
242 go func() {
243 ch := make(chan int)
244 wg := sync.WaitGroup{}
245 wg.Add(1)
246 go func() {
247 ch <- 0
248 wg.Done()
249 panic("should not be reached")
250 }()
251 wg.Wait()
252 <-ch
253 panic("should not be reached")
254 }()
255
256 for i := 0; i < yieldCount; i++ {
257 runtime.Gosched()
258 }
259 prof.WriteTo(os.Stdout, 2)
260 }
261
262 var ch = make(chan int)
263
264
265 func NoLeakGlobal() {
266 prof := pprof.Lookup("goroutineleak")
267 go func() {
268 <-ch
269 }()
270
271 for i := 0; i < yieldCount; i++ {
272 runtime.Gosched()
273 }
274 prof.WriteTo(os.Stdout, 2)
275 }
276
View as plain text