From: Michael Anthony Knyszek Date: Tue, 19 Aug 2025 19:29:55 +0000 (+0000) Subject: unique: deflake TestCanonMap/LoadOrStore/ConcurrentUnsharedKeys X-Git-Tag: go1.26rc1~1056 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=ffa882059c;p=gostls13.git unique: deflake TestCanonMap/LoadOrStore/ConcurrentUnsharedKeys I do not know yet what's causing this flake, but I've debugged it enough to be confident that it's not a serious issue; it seems to be a test flake. There is some path through which the tree nodes or keys might still be transiently reachable, but I don't yet know what that is. Details about what I tried and ruled out are in the code. For #74083. Change-Id: I97cdaf3f97e8c543fcc2ccde8b7e682893ae2f97 Reviewed-on: https://go-review.googlesource.com/c/go/+/697341 Auto-Submit: Michael Knyszek Reviewed-by: Carlos Amedee LUCI-TryBot-Result: Go LUCI --- diff --git a/src/unique/canonmap_test.go b/src/unique/canonmap_test.go index e8f56d8e00..9609d7d422 100644 --- a/src/unique/canonmap_test.go +++ b/src/unique/canonmap_test.go @@ -108,6 +108,25 @@ func testCanonMap(t *testing.T, newMap func() *canonMap[string]) { wg.Wait() } + // Run an extra GC cycle to de-flake. Sometimes the cleanups + // fail to run in time, despite drainCleanupQueue. + // + // TODO(mknyszek): Figure out why the extra GC is necessary, + // and what is transiently keeping the cleanups live. + // * I have confirmed that they are not completely stuck, and + // they always eventually run. + // * I have also confirmed it's not asynchronous preemption + // keeping them around (though that is a possibility). + // * I have confirmed that they are not simply sitting on + // the queue, and that drainCleanupQueue is just failing + // to actually empty the queue. + // * I have confirmed that it's not a write barrier that's + // keeping it alive, nor is it a weak pointer dereference + // (which shades the object during the GC). + // The corresponding objects do seem to be transiently truly + // reachable, but I have no idea by what path. + runtime.GC() + // Drain cleanups so everything is deleted. drainCleanupQueue(t)