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 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 _g_ := getg()
71 if _g_.raceignore == 0 {
72 racecall(&__tsan_go_ignore_sync_begin, _g_.racectx, 0, 0, 0)
73 }
74 _g_.raceignore++
75 }
76
77
78
79
80 func RaceEnable() {
81 _g_ := getg()
82 _g_.raceignore--
83 if _g_.raceignore == 0 {
84 racecall(&__tsan_go_ignore_sync_end, _g_.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 f := fi._Func()
175 if f != nil {
176 file, line := f.FileLine(pc)
177 if line != 0 {
178 if inldata := funcdata(fi, _FUNCDATA_InlTree); inldata != nil {
179 inltree := (*[1 << 20]inlinedCall)(inldata)
180 for {
181 ix := pcdatavalue(fi, _PCDATA_InlTreeIndex, pc, nil)
182 if ix >= 0 {
183 if inltree[ix].funcID == funcID_wrapper {
184
185
186 pc = f.Entry() + uintptr(inltree[ix].parentPc)
187 continue
188 }
189 ctx.pc = f.Entry() + uintptr(inltree[ix].parentPc)
190 ctx.fn = cfuncnameFromNameoff(fi, inltree[ix].func_)
191 ctx.line = uintptr(line)
192 ctx.file = &bytes(file)[0]
193 ctx.off = pc - f.Entry()
194 ctx.res = 1
195 return
196 }
197 break
198 }
199 }
200 ctx.fn = cfuncname(fi)
201 ctx.line = uintptr(line)
202 ctx.file = &bytes(file)[0]
203 ctx.off = pc - f.Entry()
204 ctx.res = 1
205 return
206 }
207 }
208 ctx.fn = &qq[0]
209 ctx.file = &dash[0]
210 ctx.line = 0
211 ctx.off = ctx.pc
212 ctx.res = 1
213 }
214
215 type symbolizeDataContext struct {
216 addr uintptr
217 heap uintptr
218 start uintptr
219 size uintptr
220 name *byte
221 file *byte
222 line uintptr
223 res uintptr
224 }
225
226 func raceSymbolizeData(ctx *symbolizeDataContext) {
227 if base, span, _ := findObject(ctx.addr, 0, 0); base != 0 {
228 ctx.heap = 1
229 ctx.start = base
230 ctx.size = span.elemsize
231 ctx.res = 1
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 var racedatastart uintptr
329 var racedataend uintptr
330
331
332 var racearenastart uintptr
333 var racearenaend uintptr
334
335 func racefuncenter(callpc uintptr)
336 func racefuncenterfp(fp uintptr)
337 func racefuncexit()
338 func raceread(addr uintptr)
339 func racewrite(addr uintptr)
340 func racereadrange(addr, size uintptr)
341 func racewriterange(addr, size uintptr)
342 func racereadrangepc1(addr, size, pc uintptr)
343 func racewriterangepc1(addr, size, pc uintptr)
344 func racecallbackthunk(uintptr)
345
346
347
348 func racecall(fn *byte, arg0, arg1, arg2, arg3 uintptr)
349
350
351
352 func isvalidaddr(addr unsafe.Pointer) bool {
353 return racearenastart <= uintptr(addr) && uintptr(addr) < racearenaend ||
354 racedatastart <= uintptr(addr) && uintptr(addr) < racedataend
355 }
356
357
358 func raceinit() (gctx, pctx uintptr) {
359
360 if !iscgo {
361 throw("raceinit: race build must use cgo")
362 }
363
364 racecall(&__tsan_init, uintptr(unsafe.Pointer(&gctx)), uintptr(unsafe.Pointer(&pctx)), abi.FuncPCABI0(racecallbackthunk), 0)
365
366
367 start := ^uintptr(0)
368 end := uintptr(0)
369 if start > firstmoduledata.noptrdata {
370 start = firstmoduledata.noptrdata
371 }
372 if start > firstmoduledata.data {
373 start = firstmoduledata.data
374 }
375 if start > firstmoduledata.noptrbss {
376 start = firstmoduledata.noptrbss
377 }
378 if start > firstmoduledata.bss {
379 start = firstmoduledata.bss
380 }
381 if end < firstmoduledata.enoptrdata {
382 end = firstmoduledata.enoptrdata
383 }
384 if end < firstmoduledata.edata {
385 end = firstmoduledata.edata
386 }
387 if end < firstmoduledata.enoptrbss {
388 end = firstmoduledata.enoptrbss
389 }
390 if end < firstmoduledata.ebss {
391 end = firstmoduledata.ebss
392 }
393 size := alignUp(end-start, _PageSize)
394 racecall(&__tsan_map_shadow, start, size, 0, 0)
395 racedatastart = start
396 racedataend = start + size
397
398 return
399 }
400
401 var raceFiniLock mutex
402
403
404 func racefini() {
405
406
407
408
409
410 lock(&raceFiniLock)
411
412
413 osPreemptExtEnter(getg().m)
414 racecall(&__tsan_fini, 0, 0, 0, 0)
415 }
416
417
418 func raceproccreate() uintptr {
419 var ctx uintptr
420 racecall(&__tsan_proc_create, uintptr(unsafe.Pointer(&ctx)), 0, 0, 0)
421 return ctx
422 }
423
424
425 func raceprocdestroy(ctx uintptr) {
426 racecall(&__tsan_proc_destroy, ctx, 0, 0, 0)
427 }
428
429
430 func racemapshadow(addr unsafe.Pointer, size uintptr) {
431 if racearenastart == 0 {
432 racearenastart = uintptr(addr)
433 }
434 if racearenaend < uintptr(addr)+size {
435 racearenaend = uintptr(addr) + size
436 }
437 racecall(&__tsan_map_shadow, uintptr(addr), size, 0, 0)
438 }
439
440
441 func racemalloc(p unsafe.Pointer, sz uintptr) {
442 racecall(&__tsan_malloc, 0, 0, uintptr(p), sz)
443 }
444
445
446 func racefree(p unsafe.Pointer, sz uintptr) {
447 racecall(&__tsan_free, uintptr(p), sz, 0, 0)
448 }
449
450
451 func racegostart(pc uintptr) uintptr {
452 _g_ := getg()
453 var spawng *g
454 if _g_.m.curg != nil {
455 spawng = _g_.m.curg
456 } else {
457 spawng = _g_
458 }
459
460 var racectx uintptr
461 racecall(&__tsan_go_start, spawng.racectx, uintptr(unsafe.Pointer(&racectx)), pc, 0)
462 return racectx
463 }
464
465
466 func racegoend() {
467 racecall(&__tsan_go_end, getg().racectx, 0, 0, 0)
468 }
469
470
471 func racectxend(racectx uintptr) {
472 racecall(&__tsan_go_end, racectx, 0, 0, 0)
473 }
474
475
476 func racewriterangepc(addr unsafe.Pointer, sz, callpc, pc uintptr) {
477 _g_ := getg()
478 if _g_ != _g_.m.curg {
479
480
481 return
482 }
483 if callpc != 0 {
484 racefuncenter(callpc)
485 }
486 racewriterangepc1(uintptr(addr), sz, pc)
487 if callpc != 0 {
488 racefuncexit()
489 }
490 }
491
492
493 func racereadrangepc(addr unsafe.Pointer, sz, callpc, pc uintptr) {
494 _g_ := getg()
495 if _g_ != _g_.m.curg {
496
497
498 return
499 }
500 if callpc != 0 {
501 racefuncenter(callpc)
502 }
503 racereadrangepc1(uintptr(addr), sz, pc)
504 if callpc != 0 {
505 racefuncexit()
506 }
507 }
508
509
510 func raceacquire(addr unsafe.Pointer) {
511 raceacquireg(getg(), addr)
512 }
513
514
515 func raceacquireg(gp *g, addr unsafe.Pointer) {
516 if getg().raceignore != 0 || !isvalidaddr(addr) {
517 return
518 }
519 racecall(&__tsan_acquire, gp.racectx, uintptr(addr), 0, 0)
520 }
521
522
523 func raceacquirectx(racectx uintptr, addr unsafe.Pointer) {
524 if !isvalidaddr(addr) {
525 return
526 }
527 racecall(&__tsan_acquire, racectx, uintptr(addr), 0, 0)
528 }
529
530
531 func racerelease(addr unsafe.Pointer) {
532 racereleaseg(getg(), addr)
533 }
534
535
536 func racereleaseg(gp *g, addr unsafe.Pointer) {
537 if getg().raceignore != 0 || !isvalidaddr(addr) {
538 return
539 }
540 racecall(&__tsan_release, gp.racectx, uintptr(addr), 0, 0)
541 }
542
543
544 func racereleaseacquire(addr unsafe.Pointer) {
545 racereleaseacquireg(getg(), addr)
546 }
547
548
549 func racereleaseacquireg(gp *g, addr unsafe.Pointer) {
550 if getg().raceignore != 0 || !isvalidaddr(addr) {
551 return
552 }
553 racecall(&__tsan_release_acquire, gp.racectx, uintptr(addr), 0, 0)
554 }
555
556
557 func racereleasemerge(addr unsafe.Pointer) {
558 racereleasemergeg(getg(), addr)
559 }
560
561
562 func racereleasemergeg(gp *g, addr unsafe.Pointer) {
563 if getg().raceignore != 0 || !isvalidaddr(addr) {
564 return
565 }
566 racecall(&__tsan_release_merge, gp.racectx, uintptr(addr), 0, 0)
567 }
568
569
570 func racefingo() {
571 racecall(&__tsan_finalizer_goroutine, getg().racectx, 0, 0, 0)
572 }
573
574
575
576
577
578
579 func abigen_sync_atomic_LoadInt32(addr *int32) (val int32)
580
581
582 func abigen_sync_atomic_LoadInt64(addr *int64) (val int64)
583
584
585 func abigen_sync_atomic_LoadUint32(addr *uint32) (val uint32)
586
587
588 func abigen_sync_atomic_LoadUint64(addr *uint64) (val uint64)
589
590
591 func abigen_sync_atomic_LoadUintptr(addr *uintptr) (val uintptr)
592
593
594 func abigen_sync_atomic_LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer)
595
596
597 func abigen_sync_atomic_StoreInt32(addr *int32, val int32)
598
599
600 func abigen_sync_atomic_StoreInt64(addr *int64, val int64)
601
602
603 func abigen_sync_atomic_StoreUint32(addr *uint32, val uint32)
604
605
606 func abigen_sync_atomic_StoreUint64(addr *uint64, val uint64)
607
608
609 func abigen_sync_atomic_SwapInt32(addr *int32, new int32) (old int32)
610
611
612 func abigen_sync_atomic_SwapInt64(addr *int64, new int64) (old int64)
613
614
615 func abigen_sync_atomic_SwapUint32(addr *uint32, new uint32) (old uint32)
616
617
618 func abigen_sync_atomic_SwapUint64(addr *uint64, new uint64) (old uint64)
619
620
621 func abigen_sync_atomic_AddInt32(addr *int32, delta int32) (new int32)
622
623
624 func abigen_sync_atomic_AddUint32(addr *uint32, delta uint32) (new uint32)
625
626
627 func abigen_sync_atomic_AddInt64(addr *int64, delta int64) (new int64)
628
629
630 func abigen_sync_atomic_AddUint64(addr *uint64, delta uint64) (new uint64)
631
632
633 func abigen_sync_atomic_AddUintptr(addr *uintptr, delta uintptr) (new uintptr)
634
635
636 func abigen_sync_atomic_CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool)
637
638
639 func abigen_sync_atomic_CompareAndSwapInt64(addr *int64, old, new int64) (swapped bool)
640
641
642 func abigen_sync_atomic_CompareAndSwapUint32(addr *uint32, old, new uint32) (swapped bool)
643
644
645 func abigen_sync_atomic_CompareAndSwapUint64(addr *uint64, old, new uint64) (swapped bool)
646
View as plain text