-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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/link/internal/ld: abstract origin missing local variable #25459
Comments
Let me know if/how I can help. |
Traced this to a Go bug unrelated to BoringCrypto thanks to @heschik. The DIEs refer to this function,
Here It results in this
It's referenced correctly in a few places as a
The problem is when it's referenced as a
This time you can see it has a local variable, possibly The rest of the DIE reflects just the Here's a
The same happens with @thanm, assigning this to you, but let me know if you can't work on it, or if you need help reproducing it. Also, your dwarf-check tool does not catch this because it does not return an error when Next encounters a NULL at the Offset instead of a DIE. |
Thanks for the analysis. In theory this scenario is supposed to be handled by the existing design (e.g. dead coding of locals) but clearly it's not working quite right. I will take a closer look tomorrow. |
The function of interest in this bug has a variable "d" that gets deleted by dead code elimination; dead variables are (in theory) supposed to be handled cleanly by the DWARF inline generation design, but in this case things are breaking down. There is a crude dead-code phase (source code in typecheck.go) invoked in gc.Main immediately after type checking; this particular phase will catch things like
however it will not detect things like
The case above is easily handled by the SSA backend, so 'iamdead' will not survive to the final compiled version of the function. This sort of dead variable doesn't cause any issues for the DWARF code. The problem here is that in the early deadcode phase, the typecheck.go code eliminates statically unreachable PAUTO nodes from the AST, but it doesn't delete them from the function's "Dcl" list, meaning that the DWARF inlining code still sees them (and emits references to the dead variables). When export data is generated for a package, however, the export data writer looks at the AST after the deadcode() call invoked by gc.Main(). This means that the version of sha1.New emitted into export data has no locals, which in turn means that some other package that imports "sha1" and invokes New will emit an abstract function for sha1.New that has no locals (since the Dcl list for the inlineable function is reconstructed by the importer). I think the right way to handle this is to add some code to check for unused PAUTO's (e.g. those that are statically unreachable, like "d" in sha1.New) and not process them in the DWARF code at all. The question is where to do that checking. The typechecker's deadcode phase is a bit too special-purpose for this IMHO; I will look into doing this as part of the inline analysis. |
Change https://golang.org/cl/114090 mentions this issue: |
Thank you also for reporting the problem with dwarf-check. That issue is fixed here. |
https://storage.googleapis.com/go-build-log/99c11019/linux-amd64_3ca200f0.log
The test has been failing on the BoringCrypto branch since it was introduced in fdecaa8 by @thanm, supposedly due to the BoringSSL syso object.
The text was updated successfully, but these errors were encountered: