diff --git a/src/internal/trace/generation.go b/src/internal/trace/generation.go
index 098d1d4..98bbf43 100644
--- a/src/internal/trace/generation.go
+++ b/src/internal/trace/generation.go
@@ -25,6 +25,7 @@
type generation struct {
gen uint64
batches map[ThreadID][]batch
+ batchMs []ThreadID
cpuSamples []cpuSample
*evTable
}
@@ -169,6 +170,9 @@
return err
}
default:
+ if _, ok := g.batches[b.m]; !ok {
+ g.batchMs = append(g.batchMs, b.m)
+ }
g.batches[b.m] = append(g.batches[b.m], b)
}
return nil
diff --git a/src/internal/trace/reader.go b/src/internal/trace/reader.go
index c05d5b5..8115729 100644
--- a/src/internal/trace/reader.go
+++ b/src/internal/trace/reader.go
@@ -142,7 +142,8 @@
r.cpuSamples = r.gen.cpuSamples
// Reset frontier.
- for m, batches := range r.gen.batches {
+ for _, m := range r.gen.batchMs {
+ batches := r.gen.batches[m]
bc := &batchCursor{m: m}
ok, err := bc.nextEvent(batches, r.gen.freq)
if err != nil {
diff --git a/src/internal/trace/trace_test.go b/src/internal/trace/trace_test.go
index 7dc5cbb..1929069 100644
--- a/src/internal/trace/trace_test.go
+++ b/src/internal/trace/trace_test.go
@@ -507,7 +507,7 @@
case "js", "wasip1":
t.Skip("no os.Pipe on " + runtime.GOOS)
}
- testTraceProg(t, "stress.go", nil)
+ testTraceProg(t, "stress.go", checkReaderDeterminism)
}
func TestTraceStressStartStop(t *testing.T) {
@@ -535,6 +535,43 @@
testTraceProg(t, "iter-pull.go", nil)
}
+func checkReaderDeterminism(t *testing.T, tb, _ []byte, _ bool) {
+ events := func() []trace.Event {
+ var evs []trace.Event
+
+ r, err := trace.NewReader(bytes.NewReader(tb))
+ if err != nil {
+ t.Error(err)
+ }
+ for {
+ ev, err := r.ReadEvent()
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ t.Fatal(err)
+ }
+ evs = append(evs, ev)
+ }
+
+ return evs
+ }
+
+ evs1 := events()
+ evs2 := events()
+
+ if l1, l2 := len(evs1), len(evs2); l1 != l2 {
+ t.Fatalf("re-reading trace gives different event count (%d != %d)", l1, l2)
+ }
+ for i, ev1 := range evs1 {
+ ev2 := evs2[i]
+ if s1, s2 := ev1.String(), ev2.String(); s1 != s2 {
+ t.Errorf("re-reading trace gives different event %d:\n%s\n%s\n", i, s1, s2)
+ break
+ }
+ }
+}
+
func testTraceProg(t *testing.T, progName string, extra func(t *testing.T, trace, stderr []byte, stress bool)) {
testenv.MustHaveGoRun(t)