-
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/compile: panic on conversion to anonymous interface when 2 versions of library are built #29612
Comments
Unless I'm missing something, this is a run-time panic, not a compiler panic. Any reason you assigned this to Also, were you able to reproduce this with a smaller package or Go program? |
sorry, suggest more appropriate component, please. I set cmd/compile because it looks like a compiler bug and #24547 had such component. I will try to reproduce it with a smaller program. |
I could reproduce it with much smaller program |
Also do following improvements: - show proper sublinter name for megacheck sublinters - refactor and make more simple and robust megacheck merging/optimizing - improve handling of unknown linter names in //nolint directives - minimize diff of our megacheck version from the upstream, golang/go#29612 blocks usage of the upstream version - support the new `stylecheck` linter - improve tests coverage for megacheck and nolint related cases - update and use upstream versions of unparam and interfacer instead of forked ones - don't use golangci/tools repo anymore - fix newly found issues after updating linters Relates: #314
Also do following improvements: - show proper sublinter name for megacheck sublinters - refactor and make more simple and robust megacheck merging/optimizing - improve handling of unknown linter names in //nolint directives - minimize diff of our megacheck version from the upstream, golang/go#29612 blocks usage of the upstream version - support the new `stylecheck` linter - improve tests coverage for megacheck and nolint related cases - update and use upstream versions of unparam and interfacer instead of forked ones - don't use golangci/tools repo anymore - fix newly found issues after updating linters Also should be noted that megacheck works much faster in the newest release, therefore golangci-lint works noticeably faster for large repos. Relates: #314
Also do following improvements: - show proper sublinter name for megacheck sublinters - refactor and make more simple and robust megacheck merging/optimizing - improve handling of unknown linter names in //nolint directives - minimize diff of our megacheck version from the upstream, golang/go#29612 blocks usage of the upstream version - support the new `stylecheck` linter - improve tests coverage for megacheck and nolint related cases - update and use upstream versions of unparam and interfacer instead of forked ones - don't use golangci/tools repo anymore - fix newly found issues after updating linters Also should be noted that megacheck works much faster in the newest release, therefore golangci-lint works noticeably faster for large repos. Relates: #314
Oh, I don't know if the compiler has a bug here - certainly possible, but I was wondering if you had dug up the cause. If you can reproduce the crash with a smaller self-contained program, please share it. That will make debugging the problem faster. |
Also do following improvements: - show proper sublinter name for megacheck sublinters - refactor and make more simple and robust megacheck merging/optimizing - improve handling of unknown linter names in //nolint directives - minimize diff of our megacheck version from the upstream, golang/go#29612 blocks usage of the upstream version - support the new `stylecheck` linter - improve tests coverage for megacheck and nolint related cases - update and use upstream versions of unparam and interfacer instead of forked ones - don't use golangci/tools repo anymore - fix newly found issues after updating linters Also should be noted that megacheck works much faster and consumes less memory in the newest release, therefore golangci-lint works noticeably faster and consumes less memory for large repos. Relates: #314
Also do following improvements: - show proper sublinter name for megacheck sublinters - refactor and make more simple and robust megacheck merging/optimizing - improve handling of unknown linter names in //nolint directives - minimize diff of our megacheck version from the upstream, golang/go#29612 blocks usage of the upstream version - support the new `stylecheck` linter - improve tests coverage for megacheck and nolint related cases - update and use upstream versions of unparam and interfacer instead of forked ones - don't use golangci/tools repo anymore - fix newly found issues after updating linters - megacheck is able to handle partially compiling programs Also should be noted that megacheck works much faster and consumes less memory in the newest release, therefore golangci-lint works noticeably faster and consumes less memory for large repos. Relates: #314
Also do following improvements: - show proper sublinter name for megacheck sublinters - refactor and make more simple and robust megacheck merging/optimizing - improve handling of unknown linter names in //nolint directives - minimize diff of our megacheck version from the upstream, golang/go#29612 blocks usage of the upstream version - support the new `stylecheck` linter - improve tests coverage for megacheck and nolint related cases - update and use upstream versions of unparam and interfacer instead of forked ones - don't use golangci/tools repo anymore - fix newly found issues after updating linters Also should be noted that megacheck works much faster and consumes less memory in the newest release, therefore golangci-lint works noticeably faster and consumes less memory for large repos. Relates: #314
I have already changed the description of the issue with the smaller test case:
|
Sorry, but that repo is a 404. Can you just share the file on play.golang.org? |
sorry, it was private, I made the repo a public. There are a few packages needed, I can't share it on play.golang.org |
Also do following improvements: - show proper sublinter name for megacheck sublinters - refactor and make more simple and robust megacheck merging/optimizing - improve handling of unknown linter names in //nolint directives - minimize diff of our megacheck version from the upstream, golang/go#29612 blocks usage of the upstream version - support the new `stylecheck` linter - improve tests coverage for megacheck and nolint related cases - update and use upstream versions of unparam and interfacer instead of forked ones - don't use golangci/tools repo anymore - fix newly found issues after updating linters Also should be noted that megacheck works much faster and consumes less memory in the newest release, therefore golangci-lint works noticeably faster and consumes less memory for large repos. Relates: #314
It does seem like something is very wrong. I've been able to minimize your test case to a single module with about half the amount of code, but still involving two packages with very similar types and the same package names.
This weird behavior happens on both 1.11.4 and The fact that removing the first ssa package from /cc @randall77 @ianlancetaylor @dr2chase for some input |
Broken in 1.11 too, and we're late in the cycle, so I'm leaving this for 1.13 for now. Perhaps it's reconsidered to be critical enough (or simple enough to fix) to include in 1.12. |
Interesting. This has been broken since at least Go 1.1. It works with gccgo. |
@mvdan it's a runtime bug. The interface type
Here To confirm that behavior, just changing
I'm trying to fix this bug but don't know how, I'm not too familiar with the runtime source code. One solution I'm thinking about, if the type package path ( Line 216 in 44cf595
Any idea or suggestion @ianlancetaylor ? |
Change https://golang.org/cl/157397 mentions this issue: |
I haven't looked but I'm guessing that the problem is that the two distinct interfaces have the same hash. I think the compiler or the runtime needs to include the full package path in the hash of any interface that contains an unexported method. |
@ianlancetaylor I checked and the hashes are different. The fact is that both I checked runtime and sounds like it doesn't turn |
All the type descriptor information is generated in cmd/compile/internal/gc/reflect.go. |
@ianlancetaylor I thought we think it too complicated. Just adding a condition that interface is literal or not will fix that problem. I updated the CL, please take a look. |
I don't think the updated CL is correct. It sounds like the problem is that there are two interfaces that look the same, but come from different packages, and have an unexported method. Because of the unexported method, the two interfaces should be treated as different, but the itab hash table is treating them as the same interface. If I have described the problem correctly, then that is what we have to fix: one way or another, the two different interfaces must not hash to the same entry in the itab hash table. Perhaps the reason that they are same entry in the itab hash table is that they are the same entry in the executable's symbol table. That is, perhaps the linker is merging the two types into the same symbol. If that is the case, then that is what we must fix. We must change the symbol names. |
@ianlancetaylor: Maybe I missed something, but they are not the same entry in this case, only the methods are the same. Line 216 in 5848b6c
Also it’s only matter for literal interface, named interface does not affect by this change. But literal interface can not be used outside the packge it was declared. That’s why I think add isLiteral to if condition above is enough. |
Can you clarify what you mean by that? What you mean by "the same symbol"? |
@ianlancetaylor I mean in this line Line 209 in 5848b6c
will return the same That's why I said if we add one more check for literal interface, we don't affect named interface, because they're cover by two previous conditions:
The condition Maybe I don't understand the code correctly, but for me, all interface with the same signature is shared, and they differentiate by path if not exported. |
The type |
@ianlancetaylor In
So for interface method, it doesn't set, right? That's why the import path can be empty, in that case, import path of type is used. Line 213 in 5848b6c
|
@ianlancetaylor I added some debug lines:
And the result:
For the program in the issue:
So sounds like 2 interfaces treated the same. With literal interface, the Also, |
Thanks, that seems like you have found the bug there. The code in package p2/ssa should not be seeing an interface type that has a |
@rsc @ianlancetaylor do you have any suggestion to fix this issue? |
I added a debug line in go/src/cmd/compile/internal/gc/reflect.go Line 1259 in a192507
I got:
What is |
The |
Change https://golang.org/cl/165859 mentions this issue: |
Change https://golang.org/cl/170157 mentions this issue: |
Workaround crash on go/ssa in go < 1.13. See golang/go#29612.
Workaround crash on go/ssa in go < 1.13. See golang/go#29612.
Change https://golang.org/cl/195782 mentions this issue: |
This CL expands the test for #29612 to check that type switches also work correctly when type hashes collide. Change-Id: Ia153743e6ea0736c1a33191acfe4d8ba890be527 Reviewed-on: https://go-review.googlesource.com/c/go/+/195782 Run-TryBot: Matthew Dempsky <[email protected]> Reviewed-by: Keith Randall <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
Workaround crash on go/ssa in go < 1.13. See golang/go#29612. Change-Id: I32687f6ee0baaf223248d5c1631663c73cbbfc65 GitHub-Last-Rev: 6bf28bf GitHub-Pull-Request: #162 Reviewed-on: https://go-review.googlesource.com/c/tools/+/195477 Run-TryBot: Keith Randall <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Michael Matloob <[email protected]>
See #10825. Try to match more closely the build process followed upstream: - Force module build mode, which builds the latest stable release (not master), and takes care of module replacements. - Disable cgo. - The -trimpath argument to go get requires go >= 1.13, which is also needed because go <= 1.12 has a bug that causes problems with golangci-lint², as explained in the golangci-lint installation instructions². Note that the only thing that is missing to exactly match the upstream build process is the addition of some -X variables, which only affect the data reported by golangci-lint version. ¹: golang/go#29612 ²: https://github.com/golangci/golangci-lint#install Thanks to @dbriemann and @seriousben for reporting and clarifying this issue!
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
yes it does
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Run
and got
What did you expect to see?
No panic with anonymous interface cast.
What did you see instead?
Panic.
The text was updated successfully, but these errors were encountered: