Skip to content
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: using non-stdlib packages in plugin with same go "toolchain" fails #19206

Closed
edaniels opened this issue Feb 20, 2017 · 3 comments
Closed
Milestone

Comments

@edaniels
Copy link
Contributor

edaniels commented Feb 20, 2017

What version of Go are you using (go version)?

go version go1.8 linux/amd64

What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/ec2-user/go"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build085930731=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"
PKG_CONFIG="pkg-config"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"

What did you do?

I built a go plugin using go build -buildmode=plugin. The plugin itself references a a non standard library package (e.g. github.com/org/repo). The package itself is contained in the projects vendor directory. The plugin builds successfully. The plugin is then used at a later time in the same project and same GOROOT (but not the same GOPATH). The GOPATH differs as this is on a build machine.

What did you expect to see?

I expected the plugin to be able to load with plugin.Open with the error return value set to nil

What did you see instead?

Instead I get the error message plugin.Open: plugin was built with a different version of package github.com/org/repo.

I can create some example sources if necessary but the issue is pretty straightforward.

Analysis

After digging around the shared object that is produced, there are references to the third-party package of the form /path/to/project/vendor/github.com/org/repo. Removing the need for the package in the plugin and building it again allows it to be used in a different project.

My guess would have to be that the use of absolute paths to packages used when calculating the runtime hash and link time hash for a package causes a mismatch even when the true contents of the package are the same. Logic here is based on work done in 03da269.

For any others that encounter this, relying on just toolchain provided packages (stdlib) seems to work fine in my case. If logic using third-party packages must be used, I'd suggest wrapping required methods with third-party types as interface{}. Slower but will get the job done in the meantime.

@crawshaw crawshaw self-assigned this Feb 22, 2017
@crawshaw crawshaw added this to the Go1.9 milestone Feb 22, 2017
@crawshaw
Copy link
Member

For the purposes runtime hash matching, the vendored version of a package should distinguish itself from the non-vendored version.

In a single program without plugins, including both a vendored and non-vendored dependency brings in two packages, it should do the same here.

@edaniels
Copy link
Contributor Author

edaniels commented Feb 23, 2017

So in this project the package exists in the same vendor path for both plugin and main. What's not the same is the GOPATH from which main is built. That is on machine A my GOROOT is /go and GOPATH is /home/go. I compile the plugin at /home/go/src/foo/plugin/plugin.go that imports /home/go/src/foo/vendor/bar.

I then switch my GOPATH to /build/go and build the main binary at /build/go/src/foo/ which also imports /build/go/src/foo/vendor/bar. Main loads the plugin but then fails as described above.

I believe this is difference between vendored and non-vendored in which case the plugin would open fine but the bar types would be incompatible.

Is there a specification for at which point a package path is the full path? That is, does it include the GOPATH or does it exclude it when comparing two packages' fully qualified paths (/home/go/src/foo vs foo)? The former would make this a non-bug while the latter a bug. See #12432

@crawshaw
Copy link
Member

I believe this is a duplicate of #18827.

@golang golang locked and limited conversation to collaborators Feb 23, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants