-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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
cmd/compile/internal/types2: runtime.mapassign1 throws in (*Checker.recordScope) during bootstrapping #50999
Comments
Could the compiler be re-using a types2.Info? |
(This failure mode seems to be new as of Go 1.18, but as far as I can tell it only occurs during bootstrapping; it could possibly be a bad interaction with the Go 1.4 toolchain used for bootstrapping.) |
I don't think so. The compiler only runs the types2 type checker once per process. |
The file:line numbers seem pretty odd. I know cmd/dist rewrites the files for bootstrapping, so I'd expect maybe a few lines delta, but they seem further off than I'd expect. Like just the top 3 frames within types2:
recordSelection starts at line 568
There's a call at line 642, which seems reasonably close to 648. (There are also calls at lines 588 and 631.)
The only call to selector in expr.go is at line 1458. |
Hmm, so that would rule out a race. The actual error message is this:
Can someone describe what that means exactly, and the conditions under which it could occur? That would help narrow down whether could be a problem in types2. |
@mknyszek for input on the "invalid heap pointer" error |
That is an... old message. I can't find it in the current runtime. I'll do some digging in the history but at first glance I suspect that what it's trying to say is that there's a pointer pointing outside of any span (maybe?) My guess is this is saying that at address 0xc209600c08 there's a pointer 0xc20957d000 and it's invalid. I think what it's trying to say is that the span is not a span that is currently in use by the heap (back then, the whole heap was always covered by the set of spans). I'll get back to you all in a bit. |
I'm inclined to say this is a Go 1.4 compiler (or runtime) bug. It certainly wouldn't be the first time we've been bit by the Go 1.4 toolchain when enabling new code in the compiler. E.g., this is why we currently disable inlining during bootstrapping: Lines 199 to 201 in 896df42
|
Huh, OK. So |
Because it's a pointer-past-the-end situation, this could be a compiler bug potentially too, where there's some moment that the GC could stop a goroutine and see a transiently incorrect pointer value in a stack slot or something (like at the end of a loop, maybe?). Either that, or some of the code overwritten into the source tree |
Oh! One more thing: did Go 1.4 have the "the last zero-sized field in a struct adds a byte of padding" rule? If not, I could see how taking that address in current Go is totally valid, but not valid back then. |
The compiler only uses (Though note that the unsafe.Pointer safety rules weren't established until after Go 1.4 anyway.)
I was trying to remember whether that's the case or not. I thought that became a rule when we switched from conservative to precise GC, which I thought was before Go 1.4?
Do we know for certain that it's a single 36864-byte object, or could it be multiple objects taking up that much space? |
Given #44505 — and assuming that it actually happens within the not-too-distant future — if we are reasonably confident that this is a Go 1.4 bug it might not be worth spending too much time on. (External Go users who want to build from source can already work around a Go 1.4 bug by bootstrapping from a newer Go version instead.) |
I don't think we do. This span is in range for being a small object span and it's within tail waste bounds. It's hard to say at this point what it was since the size class wasn't dumped. |
I'm pretty sure the last zero-sized field thing was added in Go 1.5 for #9401. |
Without running Go 1.4 my best guess is that the size class scheme back then is the same as today's minus the 24-byte size class (there was already the |
OK, I ran the code and there definitely are size classes with >896 byte tails but they also do not fit the description. I'm pretty convinced this is a single large object. A fun fact is that the code that we used to use for size classes is almost identical to what we use now except that we have a second pass that bumps all object sizes up within size classes to reduce tail waste. |
@golang/runtime, should we close this now that we no longer use Go 1.4 for bootstrapping? |
greplogs --dashboard -md -l -e '^goroutine \d+ .*:\n(?:.+\n\t.*\n)*(?:bootstrap/)cmd/compile/internal/types2'
2022-02-03T16:53:55-bec8a10/windows-386-2008
2021-09-07T14:53:41-21de6bc/linux-amd64-clang
(attn @griesemer, @findleyr)
The text was updated successfully, but these errors were encountered: