]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/gc: fix handling of OGETG in race mode
authorDmitry Vyukov <dvyukov@google.com>
Thu, 9 Apr 2015 07:08:29 +0000 (10:08 +0300)
committerDmitry Vyukov <dvyukov@google.com>
Fri, 10 Apr 2015 18:40:16 +0000 (18:40 +0000)
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>

src/cmd/internal/gc/inl.go
src/cmd/internal/gc/racewalk.go

index 7ba94b5031b94d6697b3847e7136d0aab76d2736..8850a8b383edc2952a030c59bf3cf9a8bd84ed50 100644 (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
        budget := maxBudget // allowed hairyness
        if ishairylist(fn.Nbody, &budget) || budget < 0 {
index ec5550171484772f8c989ba2e6902a19eaea6cf2..1efd6393c14a59f1a71ac2453136a5dc589da5a5 100644 (file)
@@ -391,7 +391,10 @@ func racewalknode(np **Node, init **NodeList, wr int, skip int) {
                // impossible nodes: only appear in backend.
        case ORROTC, OEXTEND:
                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
 
                // just do generic traversal
@@ -424,14 +427,8 @@ func racewalknode(np **Node, init **NodeList, wr int, skip int) {
                OTYPE,
                ONONAME,
                OLITERAL,
-               OSLICESTR,
-               // g is goroutine local so cannot race. Although we don't 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.
+               OSLICESTR, // always preceded by bounds checking, avoid double instrumentation.
+               OTYPESW:   // ignored by code generation, do not instrument.
                goto ret
        }