Skip to content

Commit d2b6bdb

Browse files
tpaschalisgopherbot
authored andcommitted
math/rand: make calls to Seed no-op
Makes calls to the global Seed a no-op. The GODEBUG=randseednop=0 setting can be used to revert this behavior. Fixes #67273 Change-Id: I79c1b2b23f3bc472fbd6190cb916a9d7583250f4 Reviewed-on: https://go-review.googlesource.com/c/go/+/606055 Auto-Submit: Cherry Mui <[email protected]> Reviewed-by: Cherry Mui <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent d5f7da7 commit d2b6bdb

File tree

6 files changed

+62
-0
lines changed

6 files changed

+62
-0
lines changed

doc/godebug.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,13 @@ for example,
150150
see the [runtime documentation](/pkg/runtime#hdr-Environment_Variables)
151151
and the [go command documentation](/cmd/go#hdr-Build_and_test_caching).
152152

153+
### Go 1.24
154+
155+
Go 1.24 changed the global [`math/rand.Seed`](/pkg/math/rand/#Seed) to be a
156+
no-op. This setting is controlled by the `randseednop` setting.
157+
For Go 1.24 it defaults to `randseednop=1`.
158+
Using `randseednop=0` reverts to the pre-Go 1.24 behavior.
159+
153160
### Go 1.23
154161

155162
Go 1.23 changed the channels created by package time to be unbuffered
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Calls to the deprecated top-level [Seed] function no longer have any effect. To
2+
restore the old behavior set `GODEBUG=randseednop=0`. For more background see
3+
the proposal [#67273](/issue/67273).

src/internal/godebugs/table.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ var All = []Info{
4747
{Name: "netedns0", Package: "net", Changed: 19, Old: "0"},
4848
{Name: "panicnil", Package: "runtime", Changed: 21, Old: "1"},
4949
{Name: "randautoseed", Package: "math/rand"},
50+
{Name: "randseednop", Package: "math/rand", Changed: 24, Old: "0"},
5051
{Name: "tarinsecurepath", Package: "archive/tar"},
5152
{Name: "tls10server", Package: "crypto/tls", Changed: 22, Old: "1"},
5253
{Name: "tls3des", Package: "crypto/tls", Changed: 23, Old: "1"},

src/math/rand/rand.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,9 @@ var globalRandGenerator atomic.Pointer[Rand]
313313

314314
var randautoseed = godebug.New("randautoseed")
315315

316+
// randseednop controls whether the global Seed is a no-op.
317+
var randseednop = godebug.New("randseednop")
318+
316319
// globalRand returns the generator to use for the top-level convenience
317320
// functions.
318321
func globalRand() *Rand {
@@ -391,7 +394,15 @@ func (fs *runtimeSource) read(p []byte, readVal *int64, readPos *int8) (n int, e
391394
// a random value. Programs that call Seed with a known value to get
392395
// a specific sequence of results should use New(NewSource(seed)) to
393396
// obtain a local random generator.
397+
//
398+
// As of Go 1.24 [Seed] is a no-op. To restore the previous behavior set
399+
// GODEBUG=randseednop=0.
394400
func Seed(seed int64) {
401+
if randseednop.Value() != "0" {
402+
return
403+
}
404+
randseednop.IncNonDefault()
405+
395406
orig := globalRandGenerator.Load()
396407

397408
// If we are already using a lockedSource, we can just re-seed it.

src/math/rand/rand_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,42 @@ func TestUniformFactorial(t *testing.T) {
556556
}
557557
}
558558

559+
func TestSeedNop(t *testing.T) {
560+
// If the global Seed takes effect, then resetting it to a certain value
561+
// should provide predictable output to functions using it.
562+
t.Run("randseednop=0", func(t *testing.T) {
563+
t.Setenv("GODEBUG", "randseednop=0")
564+
Seed(1)
565+
before := Int63()
566+
Seed(1)
567+
after := Int63()
568+
if before != after {
569+
t.Fatal("global Seed should take effect")
570+
}
571+
})
572+
// If calls to the global Seed are no-op then functions using it should
573+
// provide different output, even if it was reset to the same value.
574+
t.Run("randseednop=1", func(t *testing.T) {
575+
t.Setenv("GODEBUG", "randseednop=1")
576+
Seed(1)
577+
before := Int63()
578+
Seed(1)
579+
after := Int63()
580+
if before == after {
581+
t.Fatal("global Seed should be a no-op")
582+
}
583+
})
584+
t.Run("GODEBUG unset", func(t *testing.T) {
585+
Seed(1)
586+
before := Int63()
587+
Seed(1)
588+
after := Int63()
589+
if before == after {
590+
t.Fatal("global Seed should default to being a no-op")
591+
}
592+
})
593+
}
594+
559595
// Benchmarks
560596

561597
func BenchmarkInt63Threadsafe(b *testing.B) {

src/runtime/metrics/doc.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,10 @@ Below is the full list of supported metrics, ordered lexicographically.
306306
The number of non-default behaviors executed by the math/rand
307307
package due to a non-default GODEBUG=randautoseed=... setting.
308308
309+
/godebug/non-default-behavior/randseednop:events
310+
The number of non-default behaviors executed by the math/rand
311+
package due to a non-default GODEBUG=randseednop=... setting.
312+
309313
/godebug/non-default-behavior/tarinsecurepath:events
310314
The number of non-default behaviors executed by the archive/tar
311315
package due to a non-default GODEBUG=tarinsecurepath=...

0 commit comments

Comments
 (0)