Source file src/pkg/runtime/race.go
1
2
3
4
5
6
7 package runtime
8
9 import (
10 "unsafe"
11 )
12
13
14
15 func RaceRead(addr unsafe.Pointer)
16 func RaceWrite(addr unsafe.Pointer)
17 func RaceReadRange(addr unsafe.Pointer, len int)
18 func RaceWriteRange(addr unsafe.Pointer, len int)
19
20 func RaceErrors() int {
21 var n uint64
22 racecall(&__tsan_report_count, uintptr(unsafe.Pointer(&n)), 0, 0, 0)
23 return int(n)
24 }
25
26
27
28
29
30
31
32
33
34
35
36 func RaceAcquire(addr unsafe.Pointer) {
37 raceacquire(addr)
38 }
39
40
41
42
43
44
45
46
47 func RaceRelease(addr unsafe.Pointer) {
48 racerelease(addr)
49 }
50
51
52
53
54
55
56
57
58 func RaceReleaseMerge(addr unsafe.Pointer) {
59 racereleasemerge(addr)
60 }
61
62
63
64
65
66
67
68 func RaceDisable() {
69 _g_ := getg()
70 if _g_.raceignore == 0 {
71 racecall(&__tsan_go_ignore_sync_begin, _g_.racectx, 0, 0, 0)
72 }
73 _g_.raceignore++
74 }
75
76
77
78
79 func RaceEnable() {
80 _g_ := getg()
81 _g_.raceignore--
82 if _g_.raceignore == 0 {
83 racecall(&__tsan_go_ignore_sync_end, _g_.racectx, 0, 0, 0)
84 }
85 }
86
87
88
89 const raceenabled = true
90
91
92
93
94 func raceReadObjectPC(t *_type, addr unsafe.Pointer, callerpc, pc uintptr) {
95 kind := t.kind & kindMask
96 if kind == kindArray || kind == kindStruct {
97
98
99 racereadrangepc(addr, t.size, callerpc, pc)
100 } else {
101
102
103 racereadpc(addr, callerpc, pc)
104 }
105 }
106
107 func raceWriteObjectPC(t *_type, addr unsafe.Pointer, callerpc, pc uintptr) {
108 kind := t.kind & kindMask
109 if kind == kindArray || kind == kindStruct {
110
111
112 racewriterangepc(addr, t.size, callerpc, pc)
113 } else {
114
115
116 racewritepc(addr, callerpc, pc)
117 }
118 }
119
120
121 func racereadpc(addr unsafe.Pointer, callpc, pc uintptr)
122
123
124 func racewritepc(addr unsafe.Pointer, callpc, pc uintptr)
125
126 type symbolizeCodeContext struct {
127 pc uintptr
128 fn *byte
129 file *byte
130 line uintptr
131 off uintptr
132 res uintptr
133 }
134
135 var qq = [...]byte{'?', '?', 0}
136 var dash = [...]byte{'-', 0}
137
138 const (
139 raceGetProcCmd = iota
140 raceSymbolizeCodeCmd
141 raceSymbolizeDataCmd
142 )
143
144
145 func racecallback(cmd uintptr, ctx unsafe.Pointer) {
146 switch cmd {
147 case raceGetProcCmd:
148 throw("should have been handled by racecallbackthunk")
149 case raceSymbolizeCodeCmd:
150 raceSymbolizeCode((*symbolizeCodeContext)(ctx))
151 case raceSymbolizeDataCmd:
152 raceSymbolizeData((*symbolizeDataContext)(ctx))
153 default:
154 throw("unknown command")
155 }
156 }
157
158 func raceSymbolizeCode(ctx *symbolizeCodeContext) {
159 f := findfunc(ctx.pc)._Func()
160 if f != nil {
161 file, line := f.FileLine(ctx.pc)
162 if line != 0 {
163 ctx.fn = cfuncname(f.funcInfo())
164 ctx.line = uintptr(line)
165 ctx.file = &bytes(file)[0]
166 ctx.off = ctx.pc - f.Entry()
167 ctx.res = 1
168 return
169 }
170 }
171 ctx.fn = &qq[0]
172 ctx.file = &dash[0]
173 ctx.line = 0
174 ctx.off = ctx.pc
175 ctx.res = 1
176 }
177
178 type symbolizeDataContext struct {
179 addr uintptr
180 heap uintptr
181 start uintptr
182 size uintptr
183 name *byte
184 file *byte
185 line uintptr
186 res uintptr
187 }
188
189 func raceSymbolizeData(ctx *symbolizeDataContext) {
190 if base, span, _ := findObject(ctx.addr, 0, 0); base != 0 {
191 ctx.heap = 1
192 ctx.start = base
193 ctx.size = span.elemsize
194 ctx.res = 1
195 }
196 }
197
198
199
200 var __tsan_init byte
201
202
203 var __tsan_fini byte
204
205
206 var __tsan_proc_create byte
207
208
209 var __tsan_proc_destroy byte
210
211
212 var __tsan_map_shadow byte
213
214
215 var __tsan_finalizer_goroutine byte
216
217
218 var __tsan_go_start byte
219
220
221 var __tsan_go_end byte
222
223
224 var __tsan_malloc byte
225
226
227 var __tsan_free byte
228
229
230 var __tsan_acquire byte
231
232
233 var __tsan_release byte
234
235
236 var __tsan_release_merge byte
237
238
239 var __tsan_go_ignore_sync_begin byte
240
241
242 var __tsan_go_ignore_sync_end byte
243
244
245 var __tsan_report_count byte
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287 var racedatastart uintptr
288 var racedataend uintptr
289
290
291 var racearenastart uintptr
292 var racearenaend uintptr
293
294 func racefuncenter(callpc uintptr)
295 func racefuncenterfp(fp uintptr)
296 func racefuncexit()
297 func raceread(addr uintptr)
298 func racewrite(addr uintptr)
299 func racereadrange(addr, size uintptr)
300 func racewriterange(addr, size uintptr)
301 func racereadrangepc1(addr, size, pc uintptr)
302 func racewriterangepc1(addr, size, pc uintptr)
303 func racecallbackthunk(uintptr)
304
305
306
307 func racecall(fn *byte, arg0, arg1, arg2, arg3 uintptr)
308
309
310
311 func isvalidaddr(addr unsafe.Pointer) bool {
312 return racearenastart <= uintptr(addr) && uintptr(addr) < racearenaend ||
313 racedatastart <= uintptr(addr) && uintptr(addr) < racedataend
314 }
315
316
317 func raceinit() (gctx, pctx uintptr) {
318
319 if !iscgo {
320 throw("raceinit: race build must use cgo")
321 }
322
323 racecall(&__tsan_init, uintptr(unsafe.Pointer(&gctx)), uintptr(unsafe.Pointer(&pctx)), funcPC(racecallbackthunk), 0)
324
325
326 start := ^uintptr(0)
327 end := uintptr(0)
328 if start > firstmoduledata.noptrdata {
329 start = firstmoduledata.noptrdata
330 }
331 if start > firstmoduledata.data {
332 start = firstmoduledata.data
333 }
334 if start > firstmoduledata.noptrbss {
335 start = firstmoduledata.noptrbss
336 }
337 if start > firstmoduledata.bss {
338 start = firstmoduledata.bss
339 }
340 if end < firstmoduledata.enoptrdata {
341 end = firstmoduledata.enoptrdata
342 }
343 if end < firstmoduledata.edata {
344 end = firstmoduledata.edata
345 }
346 if end < firstmoduledata.enoptrbss {
347 end = firstmoduledata.enoptrbss
348 }
349 if end < firstmoduledata.ebss {
350 end = firstmoduledata.ebss
351 }
352 size := round(end-start, _PageSize)
353 racecall(&__tsan_map_shadow, start, size, 0, 0)
354 racedatastart = start
355 racedataend = start + size
356
357 return
358 }
359
360 var raceFiniLock mutex
361
362
363 func racefini() {
364
365
366
367
368
369 lock(&raceFiniLock)
370 racecall(&__tsan_fini, 0, 0, 0, 0)
371 }
372
373
374 func raceproccreate() uintptr {
375 var ctx uintptr
376 racecall(&__tsan_proc_create, uintptr(unsafe.Pointer(&ctx)), 0, 0, 0)
377 return ctx
378 }
379
380
381 func raceprocdestroy(ctx uintptr) {
382 racecall(&__tsan_proc_destroy, ctx, 0, 0, 0)
383 }
384
385
386 func racemapshadow(addr unsafe.Pointer, size uintptr) {
387 if racearenastart == 0 {
388 racearenastart = uintptr(addr)
389 }
390 if racearenaend < uintptr(addr)+size {
391 racearenaend = uintptr(addr) + size
392 }
393 racecall(&__tsan_map_shadow, uintptr(addr), size, 0, 0)
394 }
395
396
397 func racemalloc(p unsafe.Pointer, sz uintptr) {
398 racecall(&__tsan_malloc, 0, 0, uintptr(p), sz)
399 }
400
401
402 func racefree(p unsafe.Pointer, sz uintptr) {
403 racecall(&__tsan_free, uintptr(p), sz, 0, 0)
404 }
405
406
407 func racegostart(pc uintptr) uintptr {
408 _g_ := getg()
409 var spawng *g
410 if _g_.m.curg != nil {
411 spawng = _g_.m.curg
412 } else {
413 spawng = _g_
414 }
415
416 var racectx uintptr
417 racecall(&__tsan_go_start, spawng.racectx, uintptr(unsafe.Pointer(&racectx)), pc, 0)
418 return racectx
419 }
420
421
422 func racegoend() {
423 racecall(&__tsan_go_end, getg().racectx, 0, 0, 0)
424 }
425
426
427 func racewriterangepc(addr unsafe.Pointer, sz, callpc, pc uintptr) {
428 _g_ := getg()
429 if _g_ != _g_.m.curg {
430
431
432 return
433 }
434 if callpc != 0 {
435 racefuncenter(callpc)
436 }
437 racewriterangepc1(uintptr(addr), sz, pc)
438 if callpc != 0 {
439 racefuncexit()
440 }
441 }
442
443
444 func racereadrangepc(addr unsafe.Pointer, sz, callpc, pc uintptr) {
445 _g_ := getg()
446 if _g_ != _g_.m.curg {
447
448
449 return
450 }
451 if callpc != 0 {
452 racefuncenter(callpc)
453 }
454 racereadrangepc1(uintptr(addr), sz, pc)
455 if callpc != 0 {
456 racefuncexit()
457 }
458 }
459
460
461 func raceacquire(addr unsafe.Pointer) {
462 raceacquireg(getg(), addr)
463 }
464
465
466 func raceacquireg(gp *g, addr unsafe.Pointer) {
467 if getg().raceignore != 0 || !isvalidaddr(addr) {
468 return
469 }
470 racecall(&__tsan_acquire, gp.racectx, uintptr(addr), 0, 0)
471 }
472
473
474 func racerelease(addr unsafe.Pointer) {
475 racereleaseg(getg(), addr)
476 }
477
478
479 func racereleaseg(gp *g, addr unsafe.Pointer) {
480 if getg().raceignore != 0 || !isvalidaddr(addr) {
481 return
482 }
483 racecall(&__tsan_release, gp.racectx, uintptr(addr), 0, 0)
484 }
485
486
487 func racereleasemerge(addr unsafe.Pointer) {
488 racereleasemergeg(getg(), addr)
489 }
490
491
492 func racereleasemergeg(gp *g, addr unsafe.Pointer) {
493 if getg().raceignore != 0 || !isvalidaddr(addr) {
494 return
495 }
496 racecall(&__tsan_release_merge, gp.racectx, uintptr(addr), 0, 0)
497 }
498
499
500 func racefingo() {
501 racecall(&__tsan_finalizer_goroutine, getg().racectx, 0, 0, 0)
502 }
503
504
505
506
507
508
509 func abigen_sync_atomic_LoadInt32(addr *int32) (val int32)
510
511
512 func abigen_sync_atomic_LoadInt64(addr *int64) (val int64)
513
514
515 func abigen_sync_atomic_LoadUint32(addr *uint32) (val uint32)
516
517
518 func abigen_sync_atomic_LoadUint64(addr *uint64) (val uint64)
519
520
521 func abigen_sync_atomic_LoadUintptr(addr *uintptr) (val uintptr)
522
523
524 func abigen_sync_atomic_LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer)
525
526
527 func abigen_sync_atomic_StoreInt32(addr *int32, val int32)
528
529
530 func abigen_sync_atomic_StoreInt64(addr *int64, val int64)
531
532
533 func abigen_sync_atomic_StoreUint32(addr *uint32, val uint32)
534
535
536 func abigen_sync_atomic_StoreUint64(addr *uint64, val uint64)
537
538
539 func abigen_sync_atomic_SwapInt32(addr *int32, new int32) (old int32)
540
541
542 func abigen_sync_atomic_SwapInt64(addr *int64, new int64) (old int64)
543
544
545 func abigen_sync_atomic_SwapUint32(addr *uint32, new uint32) (old uint32)
546
547
548 func abigen_sync_atomic_SwapUint64(addr *uint64, new uint64) (old uint64)
549
550
551 func abigen_sync_atomic_AddInt32(addr *int32, delta int32) (new int32)
552
553
554 func abigen_sync_atomic_AddUint32(addr *uint32, delta uint32) (new uint32)
555
556
557 func abigen_sync_atomic_AddInt64(addr *int64, delta int64) (new int64)
558
559
560 func abigen_sync_atomic_AddUint64(addr *uint64, delta uint64) (new uint64)
561
562
563 func abigen_sync_atomic_AddUintptr(addr *uintptr, delta uintptr) (new uintptr)
564
565
566 func abigen_sync_atomic_CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool)
567
568
569 func abigen_sync_atomic_CompareAndSwapInt64(addr *int64, old, new int64) (swapped bool)
570
571
572 func abigen_sync_atomic_CompareAndSwapUint32(addr *uint32, old, new uint32) (swapped bool)
573
574
575 func abigen_sync_atomic_CompareAndSwapUint64(addr *uint64, old, new uint64) (swapped bool)
576
View as plain text