From 45967bb18e04fa6dc62c2786c87ce120443c64f6 Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Tue, 4 Jun 2024 14:54:55 -0700 Subject: [PATCH] runtime: soften up the GCTestIsReachable test a bit This test can fail due to objects being incorrectly retained due to conservative scanning. Allow a bit of slop (1 accidentally retained object) to prevent flaky failures. Fixes #67204 "fixes" is a bit too strong a word. More like, hopefully reduces the false positive rate to something approaching 0. Change-Id: I09984f0cce50d8209aef19f3d89b0e295c86f8d1 Reviewed-on: https://go-review.googlesource.com/c/go/+/590615 Reviewed-by: Keith Randall Reviewed-by: Michael Knyszek LUCI-TryBot-Result: Go LUCI --- src/runtime/gc_test.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/runtime/gc_test.go b/src/runtime/gc_test.go index 968d5275c5..908f632246 100644 --- a/src/runtime/gc_test.go +++ b/src/runtime/gc_test.go @@ -6,6 +6,7 @@ package runtime_test import ( "fmt" + "math/bits" "math/rand" "os" "reflect" @@ -278,8 +279,17 @@ func TestGCTestIsReachable(t *testing.T) { } got := runtime.GCTestIsReachable(all...) - if want != got { - t.Fatalf("did not get expected reachable set; want %b, got %b", want, got) + if got&want != want { + // This is a serious bug - an object is live (due to the KeepAlive + // call below), but isn't reported as such. + t.Fatalf("live object not in reachable set; want %b, got %b", want, got) + } + if bits.OnesCount64(got&^want) > 1 { + // Note: we can occasionally have a value that is retained even though + // it isn't live, due to conservative scanning of stack frames. + // See issue 67204. For now, we allow a "slop" of 1 unintentionally + // retained object. + t.Fatalf("dead object in reachable set; want %b, got %b", want, got) } runtime.KeepAlive(half) } -- 2.48.1