plugin: report the version of Go used to build a plugin when a mismatch occurs
mfreeman451 opened this issue · 3 comments
What version of Go are you using (go version
)?
$ go version go version go1.21.1 linux/amd64
Does this issue reproduce with the latest release?
Y
What operating system and processor architecture are you using (go env
)?
go env
Output
$ go env GO111MODULE='' GOARCH='amd64' GOBIN='' GOCACHE='/home/mfreeman/.cache/go-build' GOENV='/home/mfreeman/.config/go/env' GOEXE='' GOEXPERIMENT='' GOFLAGS='' GOHOSTARCH='amd64' GOHOSTOS='linux' GOINSECURE='' GOOS='linux' GOPROXY='https://proxy.golang.org,direct' GOROOT='/usr/local/go' GOSUMDB='sum.golang.org' GOTMPDIR='' GOTOOLCHAIN='auto' GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64' GOVCS='' GOVERSION='go1.21.1' GCCGO='gccgo' GOAMD64='v1' AR='ar' CC='gcc' CXX='g++' CGO_ENABLED='1' GOWORK='' CGO_CFLAGS='-O2 -g' CGO_CPPFLAGS='' CGO_CXXFLAGS='-O2 -g' CGO_FFLAGS='-O2 -g' CGO_LDFLAGS='-O2 -g' PKG_CONFIG='pkg-config' GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build4277136579=/tmp/go-build -gno-record-gcc-switches'
What did you do?
go build -buildmode=plugin -o ./handler.so ./main.go
Then when I tried to use it with another program:
2023/09/29 02:11:29 main.go:26: plugin error: plugin.Open("/plugin/handler"): plugin was built with a different version of package google.golang.org/protobuf/internal/pragma
What did you expect to see?
It should tell me what the different version is so I can match it.
What did you see instead?
Nothing other than a not very useful message telling me that I have the wrong version, but not what the correct version should be.
You can run go version -m handler.so
and go version -m <main_executable>
to find out the versions and how they differ. Would that be helpful?
You can run
go version -m handler.so
andgo version -m <main_executable>
to find out the versions and how they differ. Would that be helpful?
I'm afraid that there are some cases where go version -m
cannot help.
├── go.mod
├── go.sum
├── main.go
├── plugin
│ ├── go.mod
│ ├── go.sum
│ ├── myplugin.so
│ └── vendor
└── vendor
├── golang.org
└── modules.txt
plugin/myplugin.go
:
package main
import (
"fmt"
_ "golang.org/x/xerrors"
)
var ExportedVariable int = 42
func ExportedFunction() {
fmt.Println("Hello from the plugin!")
}
main.go
:
package main
import (
"fmt"
"plugin"
_ "golang.org/x/xerrors"
)
func main() {
p, err := plugin.Open("plugin/myplugin.so")
if err != nil {
fmt.Println("Error opening plugin:", err)
return
}
exportedVar, err := p.Lookup("ExportedVariable")
if err != nil {
fmt.Println("Error looking up variable:", err)
return
}
varValue, ok := exportedVar.(*int)
if !ok {
fmt.Println("Error getting variable value")
return
}
fmt.Println("Exported variable:", *varValue)
exportedFunc, err := p.Lookup("ExportedFunction")
if err != nil {
fmt.Println("Error looking up function:", err)
return
}
exportedFunc.(func())()
}
Build the plugin:
$ cd plugin
$ go build -buildmode=plugin -mod=vendor -o myplugin.so myplugin.go
Build the main program:
$ cd ..
$ go build -mod=vendor -o main main.go
$ ./main
Error opening plugin: plugin.Open("plugin/myplugin"): plugin was built with a different version of package golang.org/x/xerrors/internal
$ go version -m plugin/myplugin.so
plugin/myplugin.so: devel go1.22-5873bd1d7e Mon Oct 16 03:29:27 2023 +0000
path command-line-arguments
dep golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU=
build -buildmode=plugin
build -compiler=gc
build CGO_ENABLED=1
build CGO_CFLAGS=
build CGO_CPPFLAGS=
build CGO_CXXFLAGS=
build CGO_LDFLAGS=
build GOARCH=arm64
build GOOS=darwin
$ go version -m main
main: devel go1.22-5873bd1d7e Mon Oct 16 03:29:27 2023 +0000
path command-line-arguments
dep golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU=
build -buildmode=exe
build -compiler=gc
build CGO_ENABLED=1
build CGO_CFLAGS=
build CGO_CPPFLAGS=
build CGO_CXXFLAGS=
build CGO_LDFLAGS=
build GOARCH=arm64
build GOOS=darwin
It should tell me what the different version is so I can match it.
The root cause might be something else: the full file path, the build flags, ... not the package version. Moreover, I'm not sure if we can tell what the different versions are. I tried to make a change here:
diff --git a/src/runtime/plugin.go b/src/runtime/plugin.go
index 40dfefde17..33022c60f2 100644
--- a/src/runtime/plugin.go
+++ b/src/runtime/plugin.go
@@ -51,7 +51,7 @@ func plugin_lastmoduleinit() (path string, syms map[string]any, initTasks []*ini
for _, pkghash := range md.pkghashes {
if pkghash.linktimehash != *pkghash.runtimehash {
md.bad = true
- return "", nil, nil, "plugin was built with a different version of package " + pkghash.modulename
+ return "", nil, nil, "plugin was built with a different version of package " + pkghash.modulename + ": got " + *pkghash.runtimehash + ", want " + pkghash.linktimehash
}
}
but what I got is something like this:
Error opening plugin: plugin.Open("plugin/myplugin"): plugin was built with a different version of package golang.org/x/xerrors/internal: got %uV�┌, ┬▒┼├ NWIꘓ├