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/race: add const Enabled #36477

Open
ainar-g opened this issue Jan 9, 2020 · 17 comments
Open

proposal: runtime/race: add const Enabled #36477

ainar-g opened this issue Jan 9, 2020 · 17 comments
Labels
Projects
Milestone

Comments

@ainar-g
Copy link
Contributor

@ainar-g ainar-g commented Jan 9, 2020

I've seen a lot of code like this:

// +build race

package p

const race = true
// +build !race

package p

const race = false

I think it would be better to have one boolean for that, and the most logical place for it seems to be either runtime/debug or runtime/race.

@ericlagergren
Copy link
Contributor

@ericlagergren ericlagergren commented Jan 9, 2020

I’ve done this in the past to skip tests that were only useful with the -race flag set.

@ianlancetaylor ianlancetaylor changed the title runtime/debug: add const Race proposal: runtime/debug: add const Race Jan 9, 2020
@gopherbot gopherbot added this to the Proposal milestone Jan 9, 2020
@josharian
Copy link
Contributor

@josharian josharian commented Jan 9, 2020

It seems to me a more natural place for this would be runtime/race.Enabled.

@josharian
Copy link
Contributor

@josharian josharian commented Jan 9, 2020

Note that the standard library has this already in internal/race.

@ainar-g
Copy link
Contributor Author

@ainar-g ainar-g commented Jan 9, 2020

@josharian, I can send a CL with something like:

package race

import "internal/race"

// Enabled tells whether the race detector was enabled when building.
const Enabled = enabled

const enabled = race.Enabled

If the proposal is accepted.

@mvdan
Copy link
Member

@mvdan mvdan commented Mar 5, 2020

I too, have used this method manually in the past. The main counterargument here could be that one shouldn't make code behave differently when running in race mode - but that's already possible today, and I think there are plenty of legitimate use cases such as:

  • skipping tests that should only run in race mode
  • skipping tests that can't run in race mode, e.g. if they try to do a go build on a platform that doesn't support it yet
  • to propagate -race, for example if a test executes go run
@mvdan
Copy link
Member

@mvdan mvdan commented Mar 5, 2020

I also think that, long term, we could replace internal/race.Enabled with runtime/race.Enabled throughout the repository. @ainar-g I assume you want to retitle the proposal, given that it still mentions runtime/debug.Race.

@mvdan
Copy link
Member

@mvdan mvdan commented Mar 5, 2020

Here's another valid use case, I think: #37681

If the proposal is accepted, runtime/race.Enabled could be used by third party libraries to implement similar "leaked without being closed" finalizer checks.

@ainar-g ainar-g changed the title proposal: runtime/debug: add const Race proposal: runtime/race: add const Enabled Mar 5, 2020
@bcmills
Copy link
Member

@bcmills bcmills commented Mar 11, 2020

The “tests that should only run in race mode” are precisely (and only) those tests that verify run-time checks that are implemented using the race detector itself and do not build a new binary using go build or similar. (Any other check can be tested using a boolean, build tag, or environment variable.) Is that set significant at the moment? If not, perhaps a build tag suffices.

Propagating the -race flag to go run seems like a similarly niche use-case.

@bcmills
Copy link
Member

@bcmills bcmills commented Mar 11, 2020

The set of “tests that can't run in race mode” should be empty. A variable whose value is set at compile-time is too late for guarding go build (since you could reasonably build the test itself in non-race mode even on a platform for which the -race tag is fully supported). For the go build use-case, we would need a separate predicate, more like the existing cmd/internal/sys.RaceDetectorSupported.

@bcmills
Copy link
Member

@bcmills bcmills commented Mar 11, 2020

So, I agree that this would be useful in some cases, but those cases seem pretty rare — I'm not sure that they're worth the moral hazard of using the boolean to paper over actual races.

@josharian
Copy link
Contributor

@josharian josharian commented Mar 11, 2020

Another use case: In the compiler, when race mode is enabled, we randomize the order in which we compile functions. This is because the optimal ordering for performance was the least likely to flush out race conditions.

navytux added a commit to navytux/go123 that referenced this issue Apr 5, 2020
Provide race.Enabled for programs to know whether they were built with
race detector or not.

Code originates from https://lab.nexedi.com/kirr/wendelin.core/tree/25c3184d/wcfs/internal/race
See also: golang/go#36477.
@ianlancetaylor ianlancetaylor added this to Incoming in Proposals Jan 6, 2021
@josharian
Copy link
Contributor

@josharian josharian commented Feb 22, 2021

Another use case: Reducing the running time of a test in race mode. I encountered a test recently that experienced a drastic slowdown when run with -race, because of the heavy use of synchronization. Reducing the iterations with -race was the only reasonable fix I saw.

@bcmills
Copy link
Member

@bcmills bcmills commented Feb 22, 2021

@josharian, maybe? But you can also reduce the running time of a test using testing.Short, and that's more-or-less orthogonal to the race detector.

(Plus, if one of your tests fails due to memory corruption in an ordinary run, it seems unpleasant for that test to change its behavior — perhaps dramatically! — when you run it under the race detector to try to diagnose the problem.)

@josharian
Copy link
Contributor

@josharian josharian commented Feb 22, 2021

But you can also reduce the running time of a test using testing.Short, and that's more-or-less orthogonal to the race detector.

You can, but as you point out, testing.Short is orthogonal. It seems better to tie the solution to the actual problem; I'd rather go test -race complete in a reasonable length of time.

it seems unpleasant for that test to change its behavior

It doesn't. It just runs less long; it's a stress test that runs for fewer iterations. If I were investigating memory corruption, I'd run it in the loop. Or read the test and notice the line that says if race.Enabled { iterations /= 10 }.

@DeedleFake
Copy link

@DeedleFake DeedleFake commented Feb 22, 2021

Every argument in favor of this seems to be primarily for tests, not for normal code. It seems that everyone agrees that normal code should basically never do something different depending on the presence of the race detector, and that the very rare exceptions to that can be handled just fine by the build tags, as they provide enough annoyance in so implementing something that it at least discourages you from doing so.

I personally have written a manual Enabled boolean for the race detector using the build tags and I also only used it for tests. In my case, Like @josharian's case, I had tests that iterated a number of times, and the race detector degraded the performance to the point that it took a prohibitively long time to run with the race detector, as in it was timing out the CI system, but the detection of races was more than sufficient after just a few iterations, whereas the general logic test was better to run a large number of times.

I'm personally somewhat ambivalent on the presence of a boolean on top of the build tags, but, all of that being said, why not put it in something more test specific, like testing/race, or even just inside testing itself?

@josharian
Copy link
Contributor

@josharian josharian commented Feb 22, 2021

@DeedleFake sometimes you test without package testing. And sometimes the place you want to add the hook is not in a test file. See my comment: #36477 (comment).

@josharian
Copy link
Contributor

@josharian josharian commented Jun 2, 2021

Another use for this flag: When the race detector is enabled, profiling could emit warnings.

(Where and how to emit those warnings will vary; package testing might print them to stderr, third party packages might return an error from some API, etc. In an ideal world, we'd be able to write a message to the pprof output itself, which cmd/pprof would then display.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Proposals
Incoming
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
7 participants