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