1
0
mirror of https://github.com/golang/go synced 2024-10-05 23:21:21 -06:00
go/src/runtime/race.go
Dmitry Vyukov 3fc529eabe runtime: adjust program counters in race detector
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>
2015-02-20 18:04:16 +00:00

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
}