1
0
mirror of https://github.com/golang/go synced 2024-10-03 06:21:21 -06:00

cmd/gc: fix handling of OGETG in race mode

Now that getg is an intrinsic, more runtime functions
gets inlined (in particular, LockOSThread).
Runtime code gets race instrumented after inlining into
other packages. This can lead to false positives,
as race detector ignores all internal synchronization in runtime.
Inling of LockOSThread lead to false race reports on m contents.
See the issue for an example.

Fixes #10380

Change-Id: Ic9b760b53c28c2350bc54a5d4677fcd1c1f86e5f
Reviewed-on: https://go-review.googlesource.com/8690
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Dmitry Vyukov <dvyukov@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Dmitry Vyukov 2015-04-09 10:08:29 +03:00
parent 4b956ae317
commit 08c43488ee
2 changed files with 15 additions and 8 deletions

View File

@ -124,6 +124,16 @@ func caninl(fn *Node) {
} }
} }
// Runtime package must not be race instrumented.
// Racewalk skips runtime package. However, some runtime code can be
// inlined into other packages and instrumented there. To avoid this,
// we disable inlining of runtime functions in race mode.
// The example that we observed is inlining of LockOSThread,
// which lead to false race reports on m contents.
if flag_race != 0 && myimportpath == "runtime" {
return
}
const maxBudget = 80 const maxBudget = 80
budget := maxBudget // allowed hairyness budget := maxBudget // allowed hairyness
if ishairylist(fn.Nbody, &budget) || budget < 0 { if ishairylist(fn.Nbody, &budget) || budget < 0 {

View File

@ -391,7 +391,10 @@ func racewalknode(np **Node, init **NodeList, wr int, skip int) {
// impossible nodes: only appear in backend. // impossible nodes: only appear in backend.
case ORROTC, OEXTEND: case ORROTC, OEXTEND:
Yyerror("racewalk: %v cannot exist now", Oconv(int(n.Op), 0)) Yyerror("racewalk: %v cannot exist now", Oconv(int(n.Op), 0))
goto ret
case OGETG:
Yyerror("racewalk: OGETG can happen only in runtime which we don't instrument")
goto ret goto ret
// just do generic traversal // just do generic traversal
@ -424,14 +427,8 @@ func racewalknode(np **Node, init **NodeList, wr int, skip int) {
OTYPE, OTYPE,
ONONAME, ONONAME,
OLITERAL, OLITERAL,
OSLICESTR, OSLICESTR, // always preceded by bounds checking, avoid double instrumentation.
// g is goroutine local so cannot race. Although we don't instrument OTYPESW: // ignored by code generation, do not instrument.
// the runtime package, through inlining the call to runtime.getg can
// appear in non runtime packages, for example, after inlining
// runtime.LockOSThread.
OGETG,
// always preceded by bounds checking, avoid double instrumentation.
OTYPESW: // ignored by code generation, do not instrument.
goto ret goto ret
} }