Commit eec6fdc9 authored by Austin Clements's avatar Austin Clements

internal/trace: don't assume GC will start and end on same P

Currently, GC disables preemption between the traceGCStart and
traceGCDone, so it never moves Ps. Consequently, the trace verifier
attaches information about GC to its per-P state and will fail if GC
starts on one P and ends on another.

GC will soon be preemptible and may end on a different P than it
began. Hence, this change lifts this per-P verifier state to global
state.

Change-Id: I82256e2baab1ff3c4453fec312079018423b4b51
Reviewed-on: https://go-review.googlesource.com/8714Reviewed-by: default avatarDmitry Vyukov <dvyukov@google.com>
Reviewed-by: default avatarRick Hudson <rlh@golang.org>
parent 7c372496
...@@ -350,7 +350,6 @@ func postProcessTrace(events []*Event) error { ...@@ -350,7 +350,6 @@ func postProcessTrace(events []*Event) error {
type pdesc struct { type pdesc struct {
running bool running bool
g uint64 g uint64
evGC *Event
evScan *Event evScan *Event
evSweep *Event evSweep *Event
} }
...@@ -358,6 +357,7 @@ func postProcessTrace(events []*Event) error { ...@@ -358,6 +357,7 @@ func postProcessTrace(events []*Event) error {
gs := make(map[uint64]gdesc) gs := make(map[uint64]gdesc)
ps := make(map[int]pdesc) ps := make(map[int]pdesc)
gs[0] = gdesc{state: gRunning} gs[0] = gdesc{state: gRunning}
var evGC *Event
checkRunning := func(p pdesc, g gdesc, ev *Event) error { checkRunning := func(p pdesc, g gdesc, ev *Event) error {
name := EventDescriptions[ev.Type].Name name := EventDescriptions[ev.Type].Name
...@@ -389,16 +389,16 @@ func postProcessTrace(events []*Event) error { ...@@ -389,16 +389,16 @@ func postProcessTrace(events []*Event) error {
} }
p.running = false p.running = false
case EvGCStart: case EvGCStart:
if p.evGC != nil { if evGC != nil {
return fmt.Errorf("previous GC is not ended before a new one (offset %v, time %v)", ev.Off, ev.Ts) return fmt.Errorf("previous GC is not ended before a new one (offset %v, time %v)", ev.Off, ev.Ts)
} }
p.evGC = ev evGC = ev
case EvGCDone: case EvGCDone:
if p.evGC == nil { if evGC == nil {
return fmt.Errorf("bogus GC end (offset %v, time %v)", ev.Off, ev.Ts) return fmt.Errorf("bogus GC end (offset %v, time %v)", ev.Off, ev.Ts)
} }
p.evGC.Link = ev evGC.Link = ev
p.evGC = nil evGC = nil
case EvGCScanStart: case EvGCScanStart:
if p.evScan != nil { if p.evScan != nil {
return fmt.Errorf("previous scanning is not ended before a new one (offset %v, time %v)", ev.Off, ev.Ts) return fmt.Errorf("previous scanning is not ended before a new one (offset %v, time %v)", ev.Off, ev.Ts)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment