Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: runtime: add option to specify seed for globalRand #67690

Open
asubiotto opened this issue May 29, 2024 · 2 comments
Open

proposal: runtime: add option to specify seed for globalRand #67690

asubiotto opened this issue May 29, 2024 · 2 comments
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. Proposal
Milestone

Comments

@asubiotto
Copy link
Contributor

asubiotto commented May 29, 2024

Proposal Details

Note

This proposal is not concerned with the globalRand in the user-facing math/rand packages, rather the globalRand struct used to (AFAICT) seed the per-M rngs which in turn seed the runtimeSources the rand packages use as well as provide randomness for runtime decisions via cheaprand and its variants.

Proposal

Add a GORANDSEED environment variable or an equivalent option to seed runtime randomness. This environment variable will be observed in randinit roughly like so: https://github.com/polarsignals/go/blob/ea083ca4892a62eb229c1886517e1cdb575ee19a/src/runtime/rand.go#L44-L51. This effectively replaces seeding via e.g. reading /dev/urandom on unix systems and random_get in WASM.

Use case

The use case for a user-specified seed it to provide a certain level of determinism and reproducibility when testing Go programs. Throughout Go's history, accidental determinism has been avoided as much as possible by randomizing select case selection, map iteration, and even goroutine scheduling (on the local run queue only AFAICT) when running with the race detector. However, purposeful determinism is a useful property to have when testing Go programs. A GORANDSEED environment variable would be a step towards letting users control and reproduce runtime randomness.

I recently wrote a blog post that achieves purposeful determinism (or close to it) for testing. Having a way to seed the runtime's randomness was a key ingredient.

Shortcomings

GORANDSEED by itself is not enough for purposeful determinism. One also needs to control the number of OS threads, among other things, so that random number generation order is stable across test runs. However, it is a key ingredient that the developer cannot currently control. Time, for example, can be controlled via -tags=faketime, and the number of OS threads by e.g. running the test on WASM.

Alternatives

An alternative to providing a seed via an environment variable is to intercept the os-specific readRandom implementations. One could, for example, use hermit to control /dev/urandom reads on unix systems. On WASM, some runtimes also seem to allow users to intercept random_get calls. However, these solutions are per-arch while something like GORANDSEED would work across architectures.

@gopherbot gopherbot added this to the Proposal milestone May 29, 2024
@mauri870 mauri870 added the compiler/runtime Issues related to the Go compiler and/or runtime. label May 29, 2024
@mauri870
Copy link
Member

cc @golang/runtime

@brancz
Copy link
Contributor

brancz commented Jun 28, 2024

Something that has come up, to prevent people from using this and shooting themselves in the foot, a good place for this instead of an environment variable could be a flag that is only available on the go test command, so it cannot be used outside of the testing use case (people could of course still use go test -c with a single test effectively being their main but then they'd go through so much lengths that they know they're doing something terrible that they shouldn't).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. Proposal
Projects
Status: No status
Status: Incoming
Development

No branches or pull requests

4 participants