github.com/go-asm/go@v1.21.1-0.20240213172139-40c5ead50c48/trace/v2/testdata/generators/go122-confuse-seq-across-generations.go (about) 1 // Copyright 2023 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Regression test for an issue found in development. 6 // 7 // The core of the issue is that if generation counters 8 // aren't considered as part of sequence numbers, then 9 // it's possible to accidentally advance without a 10 // GoStatus event. 11 // 12 // The situation is one in which it just so happens that 13 // an event on the frontier for a following generation 14 // has a sequence number exactly one higher than the last 15 // sequence number for e.g. a goroutine in the previous 16 // generation. The parser should wait to find a GoStatus 17 // event before advancing into the next generation at all. 18 // It turns out this situation is pretty rare; the GoStatus 19 // event almost always shows up first in practice. But it 20 // can and did happen. 21 22 package main 23 24 import ( 25 "github.com/go-asm/go/trace/v2" 26 "github.com/go-asm/go/trace/v2/event/go122" 27 testgen "github.com/go-asm/go/trace/v2/github.com/go-asm/go/testgen/go122" 28 ) 29 30 func main() { 31 testgen.Main(gen) 32 } 33 34 func gen(t *testgen.Trace) { 35 g1 := t.Generation(1) 36 37 // A running goroutine blocks. 38 b10 := g1.Batch(trace.ThreadID(0), 0) 39 b10.Event("ProcStatus", trace.ProcID(0), go122.ProcRunning) 40 b10.Event("GoStatus", trace.GoID(1), trace.ThreadID(0), go122.GoRunning) 41 b10.Event("GoStop", "whatever", testgen.NoStack) 42 43 // The running goroutine gets unblocked. 44 b11 := g1.Batch(trace.ThreadID(1), 0) 45 b11.Event("ProcStatus", trace.ProcID(1), go122.ProcRunning) 46 b11.Event("GoStart", trace.GoID(1), testgen.Seq(1)) 47 b11.Event("GoStop", "whatever", testgen.NoStack) 48 49 g2 := t.Generation(2) 50 51 // Start running the goroutine, but later. 52 b21 := g2.Batch(trace.ThreadID(1), 3) 53 b21.Event("ProcStatus", trace.ProcID(1), go122.ProcRunning) 54 b21.Event("GoStart", trace.GoID(1), testgen.Seq(2)) 55 56 // The goroutine starts running, then stops, then starts again. 57 b20 := g2.Batch(trace.ThreadID(0), 5) 58 b20.Event("ProcStatus", trace.ProcID(0), go122.ProcRunning) 59 b20.Event("GoStatus", trace.GoID(1), trace.ThreadID(0), go122.GoRunnable) 60 b20.Event("GoStart", trace.GoID(1), testgen.Seq(1)) 61 b20.Event("GoStop", "whatever", testgen.NoStack) 62 }