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: loading a copy of an already loaded plugin panics #19004

Closed
campoy opened this issue Feb 9, 2017 · 10 comments
Closed

plugin: loading a copy of an already loaded plugin panics #19004

campoy opened this issue Feb 9, 2017 · 10 comments
Milestone

Comments

@campoy
Copy link
Contributor

campoy commented Feb 9, 2017

Please answer these questions before submitting your issue. Thanks!

What did you do?

Given a simple plugin hello.go:

package main

import "fmt"

func Run() { fmt.Println("Hello") }

I build it into a .so file and create a copy of the resulting file.

$ go build -buildmode=plugin hello.go
$ cp hello.so bye.so

Then running this program panics:

_, err := plugin.Open("hello.so")
if err != nil {
	log.Fatal(err)
}
_, err = plugin.Open("bye.so")
if err != nil {
	log.Fatal(err)
}

The result of the execution is:

plugin: plugin plugin/unnamed-5e323bb7e1479d9f71342c85ad29e7552ca5f746 already loaded
fatal error: plugin: plugin already loaded

goroutine 1 [running]:
runtime.throw(0x534999, 0x1d)
	/usr/local/go/src/runtime/panic.go:596 +0x95 fp=0xc420045b80 sp=0xc420045b60
plugin.lastmoduleinit(0x1e5a400, 0xc42000fb18, 0x1e5ba70, 0xc, 0x7b52a0)
	/usr/local/go/src/runtime/plugin.go:25 +0xc1a fp=0xc420045cb0 sp=0xc420045b80
plugin.open(0x530dda, 0x6, 0x0, 0x0, 0x0)
	/usr/local/go/src/plugin/plugin_dlopen.go:72 +0x25d fp=0xc420045ef0 sp=0xc420045cb0
plugin.Open(0x530dda, 0x6, 0xc42000c160, 0x0, 0x0)
	/usr/local/go/src/plugin/plugin.go:30 +0x35 fp=0xc420045f28 sp=0xc420045ef0
main.main()
	/data/main.go:39 +0xae fp=0xc420045f88 sp=0xc420045f28
runtime.main()
	/usr/local/go/src/runtime/proc.go:185 +0x20a fp=0xc420045fe0 sp=0xc420045f88
runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:2197 +0x1 fp=0xc420045fe8 sp=0xc420045fe0

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:2197 +0x1
exit status 2

What did you expect to see?

Either the second call to Open is silently ignored and no code is loaded (as it happens if I call twice Open with the same path) or Open returns an error.

What did you see instead?

A panic.

Does this issue reproduce with the latest release (go1.7.5)?

Only on Go 1.8 (plugin is required)

System details

go version devel +9799622f09 Thu Feb 9 01:45:17 2017 +0000 darwin/amd64
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/campoy"
GORACE=""
GOROOT="/Users/campoy/src/golang.org/x/go"
GOTOOLDIR="/Users/campoy/src/golang.org/x/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/yt/3jw3ts594kd9w6t6dw7rp6y40043p6/T/go-build097698135=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
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"
GOROOT/bin/go version: go version devel +9799622f09 Thu Feb 9 01:45:17 2017 +0000 darwin/amd64
GOROOT/bin/go tool compile -V: compile version devel +9799622f09 Thu Feb 9 01:45:17 2017 +0000 X:framepointer
uname -v: Darwin Kernel Version 16.4.0: Thu Dec 22 22:53:21 PST 2016; root:xnu-3789.41.3~3/RELEASE_X86_64
ProductName:	Mac OS X
ProductVersion:	10.12.3
BuildVersion:	16D32
lldb --version: lldb-360.1.70
@campoy
Copy link
Contributor Author

campoy commented Feb 9, 2017

cc @crawshaw

@vimalk78
Copy link

$ cp hello.go bye.go

should be

$ cp hello.so bye.so

@campoy
Copy link
Contributor Author

campoy commented Feb 10, 2017

Thanks @vimalk78, I fixed it

@psykhi
Copy link

psykhi commented Feb 15, 2017

@campoy Are you still experiencing this issue? My workaround is to manually set the pluginpath LD flag in the build command:

go build -ldflags "-pluginpath=hello" -buildmode=plugin -o hello.so hello.go
go build -ldflags "-pluginpath=bye" -buildmode=plugin -o bye.so bye.go

@crawshaw crawshaw self-assigned this Feb 15, 2017
@vimalk78
Copy link

@psykhi where can i find more info about this pluginpath flag

@crawshaw
Copy link
Member

Note that -pluginpath is not part of go tool interface and could change between releases. The easier way to use it now is to put your plugins in $GOPATH/src/{hello, bye} and then go build -buildmode=plugin {hello, bye}. You can create a synthetic temporary GOPATH for the purpose if you are in a script.

@psykhi
Copy link

psykhi commented Feb 16, 2017

@vimalk78 This isn't documented anywhere AFAIK, I just found that trick from reading the source code of plugin generation/opening.
@crawshaw Thanks for the tip! What will be the definitive "official" way of generating the plugins then? go build -buildmode=plugin -o hello.so hello.go ?
Will that be part of the 1.8 release?

@bradfitz bradfitz added this to the Go1.9Maybe milestone Mar 21, 2017
@tudyzhb
Copy link

tudyzhb commented Mar 24, 2017

@psykhi Thank you! To avoid panic from plugin.Open when I want to hot update a plugin, I use this command:

go build -ldflags "-pluginpath=plugin/hot-$(date +%s)" -buildmode=plugin -o hotload.so hotload.go

@psykhi
Copy link

psykhi commented Mar 27, 2017

@tudyzhb I didn't think about that one, nice! Thanks!

@bradfitz bradfitz modified the milestones: Go1.9Maybe, Go1.10 Jun 7, 2017
@gopherbot
Copy link

Change https://golang.org/cl/61171 mentions this issue: runtime, plugin: error not throw on duplicate open

@golang golang locked and limited conversation to collaborators Sep 9, 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

7 participants