mirror of
https://github.com/golang/go
synced 2024-10-05 23:21:21 -06:00
3fc529eabe
In most cases we pass return PC to race detector, and race runtime subtracts one from them. However, in manual instrumentation in runtime we pass function start PC to race runtime. Race runtime can't distinguish these cases and so it does not subtract one from top PC. This leads to bogus line numbers in some cases. Make it consistent and always pass what looks like a return PC, so that race runtime can subtract one and still get PC in the same function. Also delete two unused functions. Update #8053 Change-Id: I4242dec5e055e460c9a8990eaca1d085ae240ed2 Reviewed-on: https://go-review.googlesource.com/4902 Reviewed-by: Ian Lance Taylor <iant@golang.org>
93 lines
2.4 KiB
Go
93 lines
2.4 KiB
Go
// Copyright 2012 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// +build race
|
|
|
|
// Public race detection API, present iff build with -race.
|
|
|
|
package runtime
|
|
|
|
import (
|
|
"unsafe"
|
|
)
|
|
|
|
func RaceRead(addr unsafe.Pointer)
|
|
func RaceWrite(addr unsafe.Pointer)
|
|
func RaceReadRange(addr unsafe.Pointer, len int)
|
|
func RaceWriteRange(addr unsafe.Pointer, len int)
|
|
|
|
func RaceSemacquire(s *uint32)
|
|
func RaceSemrelease(s *uint32)
|
|
|
|
// private interface for the runtime
|
|
const raceenabled = true
|
|
|
|
// For all functions accepting callerpc and pc,
|
|
// callerpc is a return PC of the function that calls this function,
|
|
// pc is start PC of the function that calls this function.
|
|
func raceReadObjectPC(t *_type, addr unsafe.Pointer, callerpc, pc uintptr) {
|
|
kind := t.kind & kindMask
|
|
if kind == kindArray || kind == kindStruct {
|
|
// for composite objects we have to read every address
|
|
// because a write might happen to any subobject.
|
|
racereadrangepc(addr, t.size, callerpc, pc)
|
|
} else {
|
|
// for non-composite objects we can read just the start
|
|
// address, as any write must write the first byte.
|
|
racereadpc(addr, callerpc, pc)
|
|
}
|
|
}
|
|
|
|
func raceWriteObjectPC(t *_type, addr unsafe.Pointer, callerpc, pc uintptr) {
|
|
kind := t.kind & kindMask
|
|
if kind == kindArray || kind == kindStruct {
|
|
// for composite objects we have to write every address
|
|
// because a write might happen to any subobject.
|
|
racewriterangepc(addr, t.size, callerpc, pc)
|
|
} else {
|
|
// for non-composite objects we can write just the start
|
|
// address, as any write must write the first byte.
|
|
racewritepc(addr, callerpc, pc)
|
|
}
|
|
}
|
|
|
|
//go:noescape
|
|
func racereadpc(addr unsafe.Pointer, callpc, pc uintptr)
|
|
|
|
//go:noescape
|
|
func racewritepc(addr unsafe.Pointer, callpc, pc uintptr)
|
|
|
|
type symbolizeContext struct {
|
|
pc uintptr
|
|
fn *byte
|
|
file *byte
|
|
line uintptr
|
|
off uintptr
|
|
res uintptr
|
|
}
|
|
|
|
var qq = [...]byte{'?', '?', 0}
|
|
var dash = [...]byte{'-', 0}
|
|
|
|
// Callback from C into Go, runs on g0.
|
|
func racesymbolize(ctx *symbolizeContext) {
|
|
f := findfunc(ctx.pc)
|
|
if f == nil {
|
|
ctx.fn = &qq[0]
|
|
ctx.file = &dash[0]
|
|
ctx.line = 0
|
|
ctx.off = ctx.pc
|
|
ctx.res = 1
|
|
return
|
|
}
|
|
|
|
ctx.fn = cfuncname(f)
|
|
file, line := funcline(f, ctx.pc)
|
|
ctx.line = uintptr(line)
|
|
ctx.file = &bytes(file)[0] // assume NUL-terminated
|
|
ctx.off = ctx.pc - f.entry
|
|
ctx.res = 1
|
|
return
|
|
}
|