Skip to content

plugin: report the version of Go used to build a plugin when a mismatch occurs #63290

Open
@mfreeman451

Description

@mfreeman451

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.

Activity

changed the title [-]affected/package: go plugin system[/-] [+]plugin: report the version of Go used to build a plugin when a mismatch occurs[/+] on Sep 29, 2023
added
NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.
on Sep 29, 2023
cherrymui

cherrymui commented on Sep 29, 2023

@cherrymui
Member

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?

mfreeman451

mfreeman451 commented on Sep 29, 2023

@mfreeman451
Author
added this to the Backlog milestone on Oct 11, 2023
quantonganh

quantonganh commented on Oct 17, 2023

@quantonganh
Contributor

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?

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ꘓ├
thepudds

thepudds commented on Dec 30, 2024

@thepudds
Contributor

Hi @quantonganh, for your specific example in #63290 (comment), were you able to resolve the issue? Also, I’m not sure if this would help, but I’m curious if you tried building with -trimpath.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.compiler/runtimeIssues related to the Go compiler and/or runtime.help wanted

    Type

    No type

    Projects

    Status

    Todo

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @mknyszek@quantonganh@mfreeman451@gopherbot@seankhliao

        Issue actions

          plugin: report the version of Go used to build a plugin when a mismatch occurs · Issue #63290 · golang/go