diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/internal/godebugs/table.go | 1 | ||||
| -rw-r--r-- | src/math/rand/rand.go | 11 | ||||
| -rw-r--r-- | src/math/rand/rand_test.go | 36 | ||||
| -rw-r--r-- | src/runtime/metrics/doc.go | 4 |
4 files changed, 52 insertions, 0 deletions
diff --git a/src/internal/godebugs/table.go b/src/internal/godebugs/table.go index a802ac9c37..f8d30db5a3 100644 --- a/src/internal/godebugs/table.go +++ b/src/internal/godebugs/table.go @@ -47,6 +47,7 @@ var All = []Info{ {Name: "netedns0", Package: "net", Changed: 19, Old: "0"}, {Name: "panicnil", Package: "runtime", Changed: 21, Old: "1"}, {Name: "randautoseed", Package: "math/rand"}, + {Name: "randseednop", Package: "math/rand", Changed: 24, Old: "0"}, {Name: "tarinsecurepath", Package: "archive/tar"}, {Name: "tls10server", Package: "crypto/tls", Changed: 22, Old: "1"}, {Name: "tls3des", Package: "crypto/tls", Changed: 23, Old: "1"}, diff --git a/src/math/rand/rand.go b/src/math/rand/rand.go index 61ff5c1b38..4be1ca208a 100644 --- a/src/math/rand/rand.go +++ b/src/math/rand/rand.go @@ -313,6 +313,9 @@ var globalRandGenerator atomic.Pointer[Rand] var randautoseed = godebug.New("randautoseed") +// randseednop controls whether the global Seed is a no-op. +var randseednop = godebug.New("randseednop") + // globalRand returns the generator to use for the top-level convenience // functions. func globalRand() *Rand { @@ -391,7 +394,15 @@ func (fs *runtimeSource) read(p []byte, readVal *int64, readPos *int8) (n int, e // a random value. Programs that call Seed with a known value to get // a specific sequence of results should use New(NewSource(seed)) to // obtain a local random generator. +// +// As of Go 1.24 [Seed] is a no-op. To restore the previous behavior set +// GODEBUG=randseednop=0. func Seed(seed int64) { + if randseednop.Value() != "0" { + return + } + randseednop.IncNonDefault() + orig := globalRandGenerator.Load() // If we are already using a lockedSource, we can just re-seed it. diff --git a/src/math/rand/rand_test.go b/src/math/rand/rand_test.go index 7906f29674..1e1fad79ce 100644 --- a/src/math/rand/rand_test.go +++ b/src/math/rand/rand_test.go @@ -556,6 +556,42 @@ func TestUniformFactorial(t *testing.T) { } } +func TestSeedNop(t *testing.T) { + // If the global Seed takes effect, then resetting it to a certain value + // should provide predictable output to functions using it. + t.Run("randseednop=0", func(t *testing.T) { + t.Setenv("GODEBUG", "randseednop=0") + Seed(1) + before := Int63() + Seed(1) + after := Int63() + if before != after { + t.Fatal("global Seed should take effect") + } + }) + // If calls to the global Seed are no-op then functions using it should + // provide different output, even if it was reset to the same value. + t.Run("randseednop=1", func(t *testing.T) { + t.Setenv("GODEBUG", "randseednop=1") + Seed(1) + before := Int63() + Seed(1) + after := Int63() + if before == after { + t.Fatal("global Seed should be a no-op") + } + }) + t.Run("GODEBUG unset", func(t *testing.T) { + Seed(1) + before := Int63() + Seed(1) + after := Int63() + if before == after { + t.Fatal("global Seed should default to being a no-op") + } + }) +} + // Benchmarks func BenchmarkInt63Threadsafe(b *testing.B) { diff --git a/src/runtime/metrics/doc.go b/src/runtime/metrics/doc.go index da3d956d48..906abb4102 100644 --- a/src/runtime/metrics/doc.go +++ b/src/runtime/metrics/doc.go @@ -306,6 +306,10 @@ Below is the full list of supported metrics, ordered lexicographically. The number of non-default behaviors executed by the math/rand package due to a non-default GODEBUG=randautoseed=... setting. + /godebug/non-default-behavior/randseednop:events + The number of non-default behaviors executed by the math/rand + package due to a non-default GODEBUG=randseednop=... setting. + /godebug/non-default-behavior/tarinsecurepath:events The number of non-default behaviors executed by the archive/tar package due to a non-default GODEBUG=tarinsecurepath=... |
