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 22package main 23 24import ( 25 "internal/trace" 26 "internal/trace/event/go122" 27 testgen "internal/trace/internal/testgen/go122" 28) 29 30func main() { 31 testgen.Main(gen) 32} 33 34func 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} 63