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  	
   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