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