-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
plugin: package can't open plugin built with same Go runtime #21373
Comments
CC @crawshaw |
There are too many layers here for me to dig through your example, sorry. Is it possible that you have two different copies of package |
So here is a simpler reproduction of the problem from Go 1.9 (we were not experiencing problems in 1.8.3):
|
Thanks for the reproduction, that gives me an idea what's happening. Could you try patching your Go installation with https://golang.org/cl/61071 and rebuilding with make.bash? That CL doesn't look relevant, but I believe because one copy of the plugin package is built with -gcflags=-shared and one is built without, they have different version hashes, which is why you're seeing that error. (Unrelated to this issue: if the bugs I've been hunting down with CL 61071 turn out "just" to be version mismatches, maybe there's some other solution to that problem.) |
My guess about what's happening: the C/C++ compiler used by cgo to build the version of Go 1.9 you downloaded is different from your local C/C++ compiler. When you build the main binary, it uses the shipped .a files. When you build the plugin, it gets built with -shared, which requires building different .a files than the ones that came in the release, so your C/C++ compiler is invoked. The C/C++ object code in the plugin package is slightly different, so a different version hash is computed. The only general solution to this is relaxing the versioning scheme we are using. (For example, if we hashed exported APIs this wouldn't be a problem.) |
Hmm, that explanation isn't wholly satisfying, because the part of the PKGDEF being used to generate the version doesn't seem to obviously include any mention of the cgo parts of the package. |
@robmccoll I have simply been overanalyzing this. There is something off about the .a files that come with the Go 1.9 binary distribution. If you download it, then use The variants I'll work out how to unpack it and see if I can spot the difference. For now, the quick fix is |
@griesemer, @alandonovan do you have any tools for pretty printing the binary export format? I've started hacking up something using go/types, but I think it may be hiding the the minor differences between these files. |
@mdempsky see previous comment. |
Staring at the bytes revealed that the binary export data has an absolute path in it from where the 1.9 tarball was built:
when I build the .a files again with Presumably this has something to do with cgo. Still reading code. |
So it looks like absolute paths in the binary export position information is deliberate (there are calls to Is this intended, @griesemer, @mdempsky? If so, do we not care about reproducible builds for intermediate .a files? Regardless, we need a new strategy for -buildmode=shared and -buildmode=plugin, which use a hash of the export data for versioning. With absolute paths, builds cannot reproduce, and plugin versions are no use. One option would be for the compiler could generate the hash for the linker, from the export data minus the position information. Another option would be for the linker could learn to parse the export data and do it. This is more work, but may be a useful first step towards generating more useful versioning information for the non-default build modes. |
Huh - sorry I missed the updates so far. For now, we've just added rebuilding the standard library as part of the scripting for setting up our build environment. I'm curious - how were the package hash contents chosen? Were the paths really intended to be paths or is that just the overlap between the filesystem and import paths? What would be the impact of not including it? |
Change https://golang.org/cl/63693 mentions this issue: |
Is this slated for 1.9.2? |
CL 63693 is slated for 1.9.2 because of #21825. |
Change https://golang.org/cl/70975 mentions this issue: |
The compiler replaces any path of the form /path/to/goroot/src/net/port.go with GOROOT/src/net/port.go so that the same object file is produced if the GOROOT is moved. It was skipping this transformation for any absolute path into the GOROOT that came from //line directives, such as those generated by cmd/cgo. Fixes #21373 Fixes #21720 Fixes #21825 Change-Id: I2784c701b4391cfb92e23efbcb091a84957d61dd Reviewed-on: https://go-review.googlesource.com/63693 Run-TryBot: David Crawshaw <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]> Reviewed-on: https://go-review.googlesource.com/70975 Run-TryBot: Russ Cox <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
go version go1.8.3 linux/amd64
Received the following error when trying to open a plugin:
plugin.Open: plugin was built with a different version of package errors
Now, this can happen when:
However, here are reproducible steps that show that this is happening with the same version of go
Here is the
Dockerfile
being built above. As you can see, the same go installation is used to both compile both the program and the plugin:The text was updated successfully, but these errors were encountered: