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 start := ^uintptr(0)
459 end := uintptr(0)
460 if start > firstmoduledata.noptrdata {
461 start = firstmoduledata.noptrdata
462 }
463 if start > firstmoduledata.data {
464 start = firstmoduledata.data
465 }
466 if start > firstmoduledata.noptrbss {
467 start = firstmoduledata.noptrbss
468 }
469 if start > firstmoduledata.bss {
470 start = firstmoduledata.bss
471 }
472 if end < firstmoduledata.enoptrdata {
473 end = firstmoduledata.enoptrdata
474 }
475 if end < firstmoduledata.edata {
476 end = firstmoduledata.edata
477 }
478 if end < firstmoduledata.enoptrbss {
479 end = firstmoduledata.enoptrbss
480 }
481 if end < firstmoduledata.ebss {
482 end = firstmoduledata.ebss
483 }
484
485 racedatastart = start
486 racedataend = end
487
488 start = alignDown(start, _PageSize)
489 end = alignUp(end, _PageSize)
490 racecall(&__tsan_map_shadow, start, end-start, 0, 0)
491
492 return
493 }
494
495
496 func racefini() {
497
498
499
500
501
502 lock(&raceFiniLock)
503
504
505
506
507 entersyscall()
508
509
510
511 osPreemptExtEnter(getg().m)
512
513 racecall(&__tsan_fini, 0, 0, 0, 0)
514 }
515
516
517 func raceproccreate() uintptr {
518 var ctx uintptr
519 racecall(&__tsan_proc_create, uintptr(unsafe.Pointer(&ctx)), 0, 0, 0)
520 return ctx
521 }
522
523
524 func raceprocdestroy(ctx uintptr) {
525 racecall(&__tsan_proc_destroy, ctx, 0, 0, 0)
526 }
527
528
529 func racemapshadow(addr unsafe.Pointer, size uintptr) {
530 if racearenastart == 0 {
531 racearenastart = uintptr(addr)
532 }
533 if racearenaend < uintptr(addr)+size {
534 racearenaend = uintptr(addr) + size
535 }
536 racecall(&__tsan_map_shadow, uintptr(addr), size, 0, 0)
537 }
538
539
540 func racemalloc(p unsafe.Pointer, sz uintptr) {
541 racecall(&__tsan_malloc, 0, 0, uintptr(p), sz)
542 }
543
544
545 func racefree(p unsafe.Pointer, sz uintptr) {
546 racecall(&__tsan_free, uintptr(p), sz, 0, 0)
547 }
548
549
550 func racegostart(pc uintptr) uintptr {
551 gp := getg()
552 var spawng *g
553 if gp.m.curg != nil {
554 spawng = gp.m.curg
555 } else {
556 spawng = gp
557 }
558
559 var racectx uintptr
560 racecall(&__tsan_go_start, spawng.racectx, uintptr(unsafe.Pointer(&racectx)), pc, 0)
561 return racectx
562 }
563
564
565 func racegoend() {
566 racecall(&__tsan_go_end, getg().racectx, 0, 0, 0)
567 }
568
569
570 func racectxstart(pc, spawnctx uintptr) uintptr {
571 var racectx uintptr
572 racecall(&__tsan_go_start, spawnctx, uintptr(unsafe.Pointer(&racectx)), pc, 0)
573 return racectx
574 }
575
576
577 func racectxend(racectx uintptr) {
578 racecall(&__tsan_go_end, racectx, 0, 0, 0)
579 }
580
581
582 func racewriterangepc(addr unsafe.Pointer, sz, callpc, pc uintptr) {
583 gp := getg()
584 if gp != gp.m.curg {
585
586
587 return
588 }
589 if callpc != 0 {
590 racefuncenter(callpc)
591 }
592 racewriterangepc1(uintptr(addr), sz, pc)
593 if callpc != 0 {
594 racefuncexit()
595 }
596 }
597
598
599 func racereadrangepc(addr unsafe.Pointer, sz, callpc, pc uintptr) {
600 gp := getg()
601 if gp != gp.m.curg {
602
603
604 return
605 }
606 if callpc != 0 {
607 racefuncenter(callpc)
608 }
609 racereadrangepc1(uintptr(addr), sz, pc)
610 if callpc != 0 {
611 racefuncexit()
612 }
613 }
614
615
616 func raceacquire(addr unsafe.Pointer) {
617 raceacquireg(getg(), addr)
618 }
619
620
621 func raceacquireg(gp *g, addr unsafe.Pointer) {
622 if getg().raceignore != 0 || !isvalidaddr(addr) {
623 return
624 }
625 racecall(&__tsan_acquire, gp.racectx, uintptr(addr), 0, 0)
626 }
627
628
629 func raceacquirectx(racectx uintptr, addr unsafe.Pointer) {
630 if !isvalidaddr(addr) {
631 return
632 }
633 racecall(&__tsan_acquire, racectx, uintptr(addr), 0, 0)
634 }
635
636
637 func racerelease(addr unsafe.Pointer) {
638 racereleaseg(getg(), addr)
639 }
640
641
642 func racereleaseg(gp *g, addr unsafe.Pointer) {
643 if getg().raceignore != 0 || !isvalidaddr(addr) {
644 return
645 }
646 racecall(&__tsan_release, gp.racectx, uintptr(addr), 0, 0)
647 }
648
649
650 func racereleaseacquire(addr unsafe.Pointer) {
651 racereleaseacquireg(getg(), addr)
652 }
653
654
655 func racereleaseacquireg(gp *g, addr unsafe.Pointer) {
656 if getg().raceignore != 0 || !isvalidaddr(addr) {
657 return
658 }
659 racecall(&__tsan_release_acquire, gp.racectx, uintptr(addr), 0, 0)
660 }
661
662
663 func racereleasemerge(addr unsafe.Pointer) {
664 racereleasemergeg(getg(), addr)
665 }
666
667
668 func racereleasemergeg(gp *g, addr unsafe.Pointer) {
669 if getg().raceignore != 0 || !isvalidaddr(addr) {
670 return
671 }
672 racecall(&__tsan_release_merge, gp.racectx, uintptr(addr), 0, 0)
673 }
674
675
676 func racefingo() {
677 racecall(&__tsan_finalizer_goroutine, getg().racectx, 0, 0, 0)
678 }
679
680
681
682
683
684
685 func abigen_sync_atomic_LoadInt32(addr *int32) (val int32)
686
687
688 func abigen_sync_atomic_LoadInt64(addr *int64) (val int64)
689
690
691 func abigen_sync_atomic_LoadUint32(addr *uint32) (val uint32)
692
693
694 func abigen_sync_atomic_LoadUint64(addr *uint64) (val uint64)
695
696
697 func abigen_sync_atomic_LoadUintptr(addr *uintptr) (val uintptr)
698
699
700 func abigen_sync_atomic_LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer)
701
702
703 func abigen_sync_atomic_StoreInt32(addr *int32, val int32)
704
705
706 func abigen_sync_atomic_StoreInt64(addr *int64, val int64)
707
708
709 func abigen_sync_atomic_StoreUint32(addr *uint32, val uint32)
710
711
712 func abigen_sync_atomic_StoreUint64(addr *uint64, val uint64)
713
714
715 func abigen_sync_atomic_SwapInt32(addr *int32, new int32) (old int32)
716
717
718 func abigen_sync_atomic_SwapInt64(addr *int64, new int64) (old int64)
719
720
721 func abigen_sync_atomic_SwapUint32(addr *uint32, new uint32) (old uint32)
722
723
724 func abigen_sync_atomic_SwapUint64(addr *uint64, new uint64) (old uint64)
725
726
727 func abigen_sync_atomic_AddInt32(addr *int32, delta int32) (new int32)
728
729
730 func abigen_sync_atomic_AddUint32(addr *uint32, delta uint32) (new uint32)
731
732
733 func abigen_sync_atomic_AddInt64(addr *int64, delta int64) (new int64)
734
735
736 func abigen_sync_atomic_AddUint64(addr *uint64, delta uint64) (new uint64)
737
738
739 func abigen_sync_atomic_AddUintptr(addr *uintptr, delta uintptr) (new uintptr)
740
741
742 func abigen_sync_atomic_AndInt32(addr *int32, mask int32) (old int32)
743
744
745 func abigen_sync_atomic_AndUint32(addr *uint32, mask uint32) (old uint32)
746
747
748 func abigen_sync_atomic_AndInt64(addr *int64, mask int64) (old int64)
749
750
751 func abigen_sync_atomic_AndUint64(addr *uint64, mask uint64) (old uint64)
752
753
754 func abigen_sync_atomic_AndUintptr(addr *uintptr, mask uintptr) (old uintptr)
755
756
757 func abigen_sync_atomic_OrInt32(addr *int32, mask int32) (old int32)
758
759
760 func abigen_sync_atomic_OrUint32(addr *uint32, mask uint32) (old uint32)
761
762
763 func abigen_sync_atomic_OrInt64(addr *int64, mask int64) (old int64)
764
765
766 func abigen_sync_atomic_OrUint64(addr *uint64, mask uint64) (old uint64)
767
768
769 func abigen_sync_atomic_OrUintptr(addr *uintptr, mask uintptr) (old uintptr)
770
771
772 func abigen_sync_atomic_CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool)
773
774
775 func abigen_sync_atomic_CompareAndSwapInt64(addr *int64, old, new int64) (swapped bool)
776
777
778 func abigen_sync_atomic_CompareAndSwapUint32(addr *uint32, old, new uint32) (swapped bool)
779
780
781 func abigen_sync_atomic_CompareAndSwapUint64(addr *uint64, old, new uint64) (swapped bool)
782
View as plain text