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
x/tools/go/ssa: commit 75ff53bc introduced a race condition #67079
Comments
Hi, maintainer of go/ssa and author of https://go.dev/cl/538358 here. I don't have a good hypothesis yet: that CL looks sound w.r.t. concurrency, as does the same code at master. Interestingly, tinygo does not appear to use Program.RuntimeTypes or ssautil.AllFunctions (which is good: these functions should be deprecated!), which were the primary focus of that CL. The tinygo logic to construct go/ssa code looks generally sound too. Can you share the test case you used for bisecting to this CL? Even if it takes hundreds of runs to reliably fail, that would make it much easier to investigate. |
@aykevl It looks like
A lack of synchronization could be a source of races once generics are involved. (ssa.Program.Build solves this.) I don't know why https://go.dev/cl/538358 would be involved. A test case would really help. |
It's quite safe to go/ssa-Build all Packages in parallel--that's exactly what Program.Build does--so that doesn't explain it. tinygo seems to use concurrency for building and compiling each SSA package in parallel while respecting topological order, which seems sound. (There's more available parallelism of course, in reading, parsing, type-checking, etc.) The only synchronization within each compile job (package) is a cross-process lock on the output file, presumably to prevent concurrent writes from different tinygo processes. There's no fine-grained concurrency, so the lack of Mutex.Lock operations isn't obviously a problem. I wonder about the fact that some functions in low-level packages of intrinsics (runtime et al) are used from all other packages (e.g. when compiling ssa.Go); if the intrinsics package is not fully llvm-built before the other packages this could lead to a race.
Agreed. |
ssa is very careful to only read from specific fixed fields on functions from other packages or created functions while building. Reading from generic instantiations before they are done can race. Waiting for every package to finish building is good enough, which is what ssa.Program does. Annoyingly diamonds can cause the same instantiation to be created so package topology is not enough. This definitely used to be the case, and I don't remember fixing this. (My memory might be off though.) |
That sounds very much like the behavior I have observed anecdotally. However, I do not have a reproducible test case. |
Go version
go version go1.22.2 linux/arm64
Output of
go env
in your module/workspace:What did you do?
I upgraded the x/tools package to v0.17.0.
What did you see happen?
Lots of infrequent crashes starting from golang/tools@75ff53b (see tinygo-org/tinygo#4206).
The symptoms are all kinds of weird crashes, but in particular what I'm seeing often is functions that appear to be unfinished (no terminator in a basic block).
Interestingly, once I build the program using
-race
the race condition goes away. This makes it particularly difficult to pinpoint where exactly the bug is located.I've also tried the master branch (golang/tools@0b45163) but sadly it still shows the same crashes.
I can try to work on a standalone reproducer, but with the nature of this crash it's difficult to find one. Still, if it's difficult to find the culprit just from the bisected commit I can try to work on a reproducer.
What did you expect to see?
No race condition.
The text was updated successfully, but these errors were encountered: