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