Source file
src/runtime/race.go
1
2
3
4
5
6
7 package runtime
8
9 import (
10 "internal/abi"
11 "unsafe"
12 )
13
14
15
16 func RaceRead(addr unsafe.Pointer)
17
18
19
20 func race_Read(addr unsafe.Pointer) {
21 RaceRead(addr)
22 }
23
24 func RaceWrite(addr unsafe.Pointer)
25
26
27
28 func race_Write(addr unsafe.Pointer) {
29 RaceWrite(addr)
30 }
31
32 func RaceReadRange(addr unsafe.Pointer, len int)
33
34
35
36 func race_ReadRange(addr unsafe.Pointer, len int) {
37 RaceReadRange(addr, len)
38 }
39
40 func RaceWriteRange(addr unsafe.Pointer, len int)
41
42
43
44 func race_WriteRange(addr unsafe.Pointer, len int) {
45 RaceWriteRange(addr, len)
46 }
47
48 func RaceErrors() int {
49 var n uint64
50 racecall(&__tsan_report_count, uintptr(unsafe.Pointer(&n)), 0, 0, 0)
51 return int(n)
52 }
53
54
55
56 func race_Errors() int {
57 return RaceErrors()
58 }
59
60
61
62
63
64
65
66
67
68
69
70 func RaceAcquire(addr unsafe.Pointer) {
71 raceacquire(addr)
72 }
73
74
75
76 func race_Acquire(addr unsafe.Pointer) {
77 RaceAcquire(addr)
78 }
79
80
81
82
83
84
85
86
87 func RaceRelease(addr unsafe.Pointer) {
88 racerelease(addr)
89 }
90
91
92
93 func race_Release(addr unsafe.Pointer) {
94 RaceRelease(addr)
95 }
96
97
98
99
100
101
102
103
104 func RaceReleaseMerge(addr unsafe.Pointer) {
105 racereleasemerge(addr)
106 }
107
108
109
110 func race_ReleaseMerge(addr unsafe.Pointer) {
111 RaceReleaseMerge(addr)
112 }
113
114
115
116
117
118
119
120 func RaceDisable() {
121 gp := getg()
122 if gp.raceignore == 0 {
123 racecall(&__tsan_go_ignore_sync_begin, gp.racectx, 0, 0, 0)
124 }
125 gp.raceignore++
126 }
127
128
129
130 func race_Disable() {
131 RaceDisable()
132 }
133
134
135
136
137 func RaceEnable() {
138 gp := getg()
139 gp.raceignore--
140 if gp.raceignore == 0 {
141 racecall(&__tsan_go_ignore_sync_end, gp.racectx, 0, 0, 0)
142 }
143 }
144
145
146
147 func race_Enable() {
148 RaceEnable()
149 }
150
151
152
153 const raceenabled = true
154
155
156
157
158 func raceReadObjectPC(t *_type, addr unsafe.Pointer, callerpc, pc uintptr) {
159 kind := t.Kind_ & abi.KindMask
160 if kind == abi.Array || kind == abi.Struct {
161
162
163 racereadrangepc(addr, t.Size_, callerpc, pc)
164 } else {
165
166
167 racereadpc(addr, callerpc, pc)
168 }
169 }
170
171
172 func race_ReadObjectPC(t *abi.Type, addr unsafe.Pointer, callerpc, pc uintptr) {
173 raceReadObjectPC(t, addr, callerpc, pc)
174 }
175
176 func raceWriteObjectPC(t *_type, addr unsafe.Pointer, callerpc, pc uintptr) {
177 kind := t.Kind_ & abi.KindMask
178 if kind == abi.Array || kind == abi.Struct {
179
180
181 racewriterangepc(addr, t.Size_, callerpc, pc)
182 } else {
183
184
185 racewritepc(addr, callerpc, pc)
186 }
187 }
188
189
190 func race_WriteObjectPC(t *abi.Type, addr unsafe.Pointer, callerpc, pc uintptr) {
191 raceWriteObjectPC(t, addr, callerpc, pc)
192 }
193
194
195 func racereadpc(addr unsafe.Pointer, callpc, pc uintptr)
196
197
198 func racewritepc(addr unsafe.Pointer, callpc, pc uintptr)
199
200
201 func race_ReadPC(addr unsafe.Pointer, callerpc, pc uintptr) {
202 racereadpc(addr, callerpc, pc)
203 }
204
205
206 func race_WritePC(addr unsafe.Pointer, callerpc, pc uintptr) {
207 racewritepc(addr, callerpc, pc)
208 }
209
210 type symbolizeCodeContext struct {
211 pc uintptr
212 fn *byte
213 file *byte
214 line uintptr
215 off uintptr
216 res uintptr
217 }
218
219 var qq = [...]byte{'?', '?', 0}
220 var dash = [...]byte{'-', 0}
221
222 const (
223 raceGetProcCmd = iota
224 raceSymbolizeCodeCmd
225 raceSymbolizeDataCmd
226 )
227
228
229 func racecallback(cmd uintptr, ctx unsafe.Pointer) {
230 switch cmd {
231 case raceGetProcCmd:
232 throw("should have been handled by racecallbackthunk")
233 case raceSymbolizeCodeCmd:
234 raceSymbolizeCode((*symbolizeCodeContext)(ctx))
235 case raceSymbolizeDataCmd:
236 raceSymbolizeData((*symbolizeDataContext)(ctx))
237 default:
238 throw("unknown command")
239 }
240 }
241
242
243
244
245
246
247
248
249
250
251
252
253
254 func raceSymbolizeCode(ctx *symbolizeCodeContext) {
255 pc := ctx.pc
256 fi := findfunc(pc)
257 if fi.valid() {
258 u, uf := newInlineUnwinder(fi, pc)
259 for ; uf.valid(); uf = u.next(uf) {
260 sf := u.srcFunc(uf)
261 if sf.funcID == abi.FuncIDWrapper && u.isInlined(uf) {
262
263
264
265
266 continue
267 }
268
269 name := sf.name()
270 file, line := u.fileLine(uf)
271 if line == 0 {
272
273 continue
274 }
275 ctx.fn = &bytes(name)[0]
276 ctx.line = uintptr(line)
277 ctx.file = &bytes(file)[0]
278 ctx.off = pc - fi.entry()
279 ctx.res = 1
280 if u.isInlined(uf) {
281
282
283 uf = u.next(uf)
284 ctx.pc = uf.pc
285 }
286 return
287 }
288 }
289 ctx.fn = &qq[0]
290 ctx.file = &dash[0]
291 ctx.line = 0
292 ctx.off = ctx.pc
293 ctx.res = 1
294 }
295
296 type symbolizeDataContext struct {
297 addr uintptr
298 heap uintptr
299 start uintptr
300 size uintptr
301 name *byte
302 file *byte
303 line uintptr
304 res uintptr
305 }
306
307 func raceSymbolizeData(ctx *symbolizeDataContext) {
308 if base, span, _ := findObject(ctx.addr, 0, 0); base != 0 {
309
310 ctx.heap = 1
311 ctx.start = base
312 ctx.size = span.elemsize
313 ctx.res = 1
314 }
315 }
316
317
318
319
320 var __tsan_init byte
321
322
323 var __tsan_fini byte
324
325
326 var __tsan_proc_create byte
327
328
329 var __tsan_proc_destroy byte
330
331
332 var __tsan_map_shadow byte
333
334
335 var __tsan_finalizer_goroutine byte
336
337
338 var __tsan_go_start byte
339
340
341 var __tsan_go_end byte
342
343
344 var __tsan_malloc byte
345
346
347 var __tsan_free byte
348
349
350 var __tsan_acquire byte
351
352
353 var __tsan_release byte
354
355
356 var __tsan_release_acquire byte
357
358
359 var __tsan_release_merge byte
360
361
362 var __tsan_go_ignore_sync_begin byte
363
364
365 var __tsan_go_ignore_sync_end byte
366
367
368 var __tsan_report_count byte
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417 var racedatastart uintptr
418 var racedataend uintptr
419
420
421 var racearenastart uintptr
422 var racearenaend uintptr
423
424 func racefuncenter(callpc uintptr)
425 func racefuncenterfp(fp uintptr)
426 func racefuncexit()
427 func raceread(addr uintptr)
428 func racewrite(addr uintptr)
429 func racereadrange(addr, size uintptr)
430 func racewriterange(addr, size uintptr)
431 func racereadrangepc1(addr, size, pc uintptr)
432 func racewriterangepc1(addr, size, pc uintptr)
433 func racecallbackthunk(uintptr)
434
435
436
437 func racecall(fn *byte, arg0, arg1, arg2, arg3 uintptr)
438
439
440
441
442 func isvalidaddr(addr unsafe.Pointer) bool {
443 return racearenastart <= uintptr(addr) && uintptr(addr) < racearenaend ||
444 racedatastart <= uintptr(addr) && uintptr(addr) < racedataend
445 }
446
447
448 func raceinit() (gctx, pctx uintptr) {
449 lockInit(&raceFiniLock, lockRankRaceFini)
450
451
452 if !iscgo && GOOS != "darwin" {
453 throw("raceinit: race build must use cgo")
454 }
455
456 racecall(&__tsan_init, uintptr(unsafe.Pointer(&gctx)), uintptr(unsafe.Pointer(&pctx)), abi.FuncPCABI0(racecallbackthunk), 0)
457
458
459 start := ^uintptr(0)
460 end := uintptr(0)
461 if start > firstmoduledata.noptrdata {
462 start = firstmoduledata.noptrdata
463 }
464 if start > firstmoduledata.data {
465 start = firstmoduledata.data
466 }
467 if start > firstmoduledata.noptrbss {
468 start = firstmoduledata.noptrbss
469 }
470 if start > firstmoduledata.bss {
471 start = firstmoduledata.bss
472 }
473 if end < firstmoduledata.enoptrdata {
474 end = firstmoduledata.enoptrdata
475 }
476 if end < firstmoduledata.edata {
477 end = firstmoduledata.edata
478 }
479 if end < firstmoduledata.enoptrbss {
480 end = firstmoduledata.enoptrbss
481 }
482 if end < firstmoduledata.ebss {
483 end = firstmoduledata.ebss
484 }
485 size := alignUp(end-start, _PageSize)
486 racecall(&__tsan_map_shadow, start, size, 0, 0)
487 racedatastart = start
488 racedataend = start + size
489
490 return
491 }
492
493
494 func racefini() {
495
496
497
498
499
500 lock(&raceFiniLock)
501
502
503
504
505 entersyscall()
506
507
508
509 osPreemptExtEnter(getg().m)
510
511 racecall(&__tsan_fini, 0, 0, 0, 0)
512 }
513
514
515 func raceproccreate() uintptr {
516 var ctx uintptr
517 racecall(&__tsan_proc_create, uintptr(unsafe.Pointer(&ctx)), 0, 0, 0)
518 return ctx
519 }
520
521
522 func raceprocdestroy(ctx uintptr) {
523 racecall(&__tsan_proc_destroy, ctx, 0, 0, 0)
524 }
525
526
527 func racemapshadow(addr unsafe.Pointer, size uintptr) {
528 if racearenastart == 0 {
529 racearenastart = uintptr(addr)
530 }
531 if racearenaend < uintptr(addr)+size {
532 racearenaend = uintptr(addr) + size
533 }
534 racecall(&__tsan_map_shadow, uintptr(addr), size, 0, 0)
535 }
536
537
538 func racemalloc(p unsafe.Pointer, sz uintptr) {
539 racecall(&__tsan_malloc, 0, 0, uintptr(p), sz)
540 }
541
542
543 func racefree(p unsafe.Pointer, sz uintptr) {
544 racecall(&__tsan_free, uintptr(p), sz, 0, 0)
545 }
546
547
548 func racegostart(pc uintptr) uintptr {
549 gp := getg()
550 var spawng *g
551 if gp.m.curg != nil {
552 spawng = gp.m.curg
553 } else {
554 spawng = gp
555 }
556
557 var racectx uintptr
558 racecall(&__tsan_go_start, spawng.racectx, uintptr(unsafe.Pointer(&racectx)), pc, 0)
559 return racectx
560 }
561
562
563 func racegoend() {
564 racecall(&__tsan_go_end, getg().racectx, 0, 0, 0)
565 }
566
567
568 func racectxend(racectx uintptr) {
569 racecall(&__tsan_go_end, racectx, 0, 0, 0)
570 }
571
572
573 func racewriterangepc(addr unsafe.Pointer, sz, callpc, pc uintptr) {
574 gp := getg()
575 if gp != gp.m.curg {
576
577
578 return
579 }
580 if callpc != 0 {
581 racefuncenter(callpc)
582 }
583 racewriterangepc1(uintptr(addr), sz, pc)
584 if callpc != 0 {
585 racefuncexit()
586 }
587 }
588
589
590 func racereadrangepc(addr unsafe.Pointer, sz, callpc, pc uintptr) {
591 gp := getg()
592 if gp != gp.m.curg {
593
594
595 return
596 }
597 if callpc != 0 {
598 racefuncenter(callpc)
599 }
600 racereadrangepc1(uintptr(addr), sz, pc)
601 if callpc != 0 {
602 racefuncexit()
603 }
604 }
605
606
607 func raceacquire(addr unsafe.Pointer) {
608 raceacquireg(getg(), addr)
609 }
610
611
612 func raceacquireg(gp *g, addr unsafe.Pointer) {
613 if getg().raceignore != 0 || !isvalidaddr(addr) {
614 return
615 }
616 racecall(&__tsan_acquire, gp.racectx, uintptr(addr), 0, 0)
617 }
618
619
620 func raceacquirectx(racectx uintptr, addr unsafe.Pointer) {
621 if !isvalidaddr(addr) {
622 return
623 }
624 racecall(&__tsan_acquire, racectx, uintptr(addr), 0, 0)
625 }
626
627
628 func racerelease(addr unsafe.Pointer) {
629 racereleaseg(getg(), addr)
630 }
631
632
633 func racereleaseg(gp *g, addr unsafe.Pointer) {
634 if getg().raceignore != 0 || !isvalidaddr(addr) {
635 return
636 }
637 racecall(&__tsan_release, gp.racectx, uintptr(addr), 0, 0)
638 }
639
640
641 func racereleaseacquire(addr unsafe.Pointer) {
642 racereleaseacquireg(getg(), addr)
643 }
644
645
646 func racereleaseacquireg(gp *g, addr unsafe.Pointer) {
647 if getg().raceignore != 0 || !isvalidaddr(addr) {
648 return
649 }
650 racecall(&__tsan_release_acquire, gp.racectx, uintptr(addr), 0, 0)
651 }
652
653
654 func racereleasemerge(addr unsafe.Pointer) {
655 racereleasemergeg(getg(), addr)
656 }
657
658
659 func racereleasemergeg(gp *g, addr unsafe.Pointer) {
660 if getg().raceignore != 0 || !isvalidaddr(addr) {
661 return
662 }
663 racecall(&__tsan_release_merge, gp.racectx, uintptr(addr), 0, 0)
664 }
665
666
667 func racefingo() {
668 racecall(&__tsan_finalizer_goroutine, getg().racectx, 0, 0, 0)
669 }
670
671
672
673
674
675
676 func abigen_sync_atomic_LoadInt32(addr *int32) (val int32)
677
678
679 func abigen_sync_atomic_LoadInt64(addr *int64) (val int64)
680
681
682 func abigen_sync_atomic_LoadUint32(addr *uint32) (val uint32)
683
684
685 func abigen_sync_atomic_LoadUint64(addr *uint64) (val uint64)
686
687
688 func abigen_sync_atomic_LoadUintptr(addr *uintptr) (val uintptr)
689
690
691 func abigen_sync_atomic_LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer)
692
693
694 func abigen_sync_atomic_StoreInt32(addr *int32, val int32)
695
696
697 func abigen_sync_atomic_StoreInt64(addr *int64, val int64)
698
699
700 func abigen_sync_atomic_StoreUint32(addr *uint32, val uint32)
701
702
703 func abigen_sync_atomic_StoreUint64(addr *uint64, val uint64)
704
705
706 func abigen_sync_atomic_SwapInt32(addr *int32, new int32) (old int32)
707
708
709 func abigen_sync_atomic_SwapInt64(addr *int64, new int64) (old int64)
710
711
712 func abigen_sync_atomic_SwapUint32(addr *uint32, new uint32) (old uint32)
713
714
715 func abigen_sync_atomic_SwapUint64(addr *uint64, new uint64) (old uint64)
716
717
718 func abigen_sync_atomic_AddInt32(addr *int32, delta int32) (new int32)
719
720
721 func abigen_sync_atomic_AddUint32(addr *uint32, delta uint32) (new uint32)
722
723
724 func abigen_sync_atomic_AddInt64(addr *int64, delta int64) (new int64)
725
726
727 func abigen_sync_atomic_AddUint64(addr *uint64, delta uint64) (new uint64)
728
729
730 func abigen_sync_atomic_AddUintptr(addr *uintptr, delta uintptr) (new uintptr)
731
732
733 func abigen_sync_atomic_AndInt32(addr *int32, mask int32) (old int32)
734
735
736 func abigen_sync_atomic_AndUint32(addr *uint32, mask uint32) (old uint32)
737
738
739 func abigen_sync_atomic_AndInt64(addr *int64, mask int64) (old int64)
740
741
742 func abigen_sync_atomic_AndUint64(addr *uint64, mask uint64) (old uint64)
743
744
745 func abigen_sync_atomic_AndUintptr(addr *uintptr, mask uintptr) (old uintptr)
746
747
748 func abigen_sync_atomic_OrInt32(addr *int32, mask int32) (old int32)
749
750
751 func abigen_sync_atomic_OrUint32(addr *uint32, mask uint32) (old uint32)
752
753
754 func abigen_sync_atomic_OrInt64(addr *int64, mask int64) (old int64)
755
756
757 func abigen_sync_atomic_OrUint64(addr *uint64, mask uint64) (old uint64)
758
759
760 func abigen_sync_atomic_OrUintptr(addr *uintptr, mask uintptr) (old uintptr)
761
762
763 func abigen_sync_atomic_CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool)
764
765
766 func abigen_sync_atomic_CompareAndSwapInt64(addr *int64, old, new int64) (swapped bool)
767
768
769 func abigen_sync_atomic_CompareAndSwapUint32(addr *uint32, old, new uint32) (swapped bool)
770
771
772 func abigen_sync_atomic_CompareAndSwapUint64(addr *uint64, old, new uint64) (swapped bool)
773
View as plain text