• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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