aboutsummaryrefslogtreecommitdiff
path: root/src/plugin/plugin_dlopen.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugin/plugin_dlopen.go')
-rw-r--r--src/plugin/plugin_dlopen.go26
1 files changed, 16 insertions, 10 deletions
diff --git a/src/plugin/plugin_dlopen.go b/src/plugin/plugin_dlopen.go
index ce66c036c9..37380989d7 100644
--- a/src/plugin/plugin_dlopen.go
+++ b/src/plugin/plugin_dlopen.go
@@ -87,7 +87,7 @@ func open(name string) (*Plugin, error) {
if C.realpath(
(*C.char)(unsafe.Pointer(&cRelName[0])),
(*C.char)(unsafe.Pointer(&cPath[0]))) == nil {
- return nil, errors.New("plugin.Open(" + name + "): realpath failed")
+ return nil, errors.New(`plugin.Open("` + name + `"): realpath failed`)
}
filepath := C.GoString((*C.char)(unsafe.Pointer(&cPath[0])))
@@ -95,6 +95,9 @@ func open(name string) (*Plugin, error) {
pluginsMu.Lock()
if p := plugins[filepath]; p != nil {
pluginsMu.Unlock()
+ if p.err != "" {
+ return nil, errors.New(`plugin.Open("` + name + `"): ` + p.err + ` (previous failure)`)
+ }
<-p.loaded
return p, nil
}
@@ -102,22 +105,25 @@ func open(name string) (*Plugin, error) {
h := C.pluginOpen((*C.char)(unsafe.Pointer(&cPath[0])), &cErr)
if h == 0 {
pluginsMu.Unlock()
- return nil, errors.New("plugin.Open: " + C.GoString(cErr))
+ return nil, errors.New(`plugin.Open("` + name + `"): ` + C.GoString(cErr))
}
// TODO(crawshaw): look for plugin note, confirm it is a Go plugin
// and it was built with the correct toolchain.
if len(name) > 3 && name[len(name)-3:] == ".so" {
name = name[:len(name)-3]
}
-
- pluginpath, syms, mismatchpkg := lastmoduleinit()
- if mismatchpkg != "" {
- pluginsMu.Unlock()
- return nil, errors.New("plugin.Open: plugin was built with a different version of package " + mismatchpkg)
- }
if plugins == nil {
plugins = make(map[string]*Plugin)
}
+ pluginpath, syms, errstr := lastmoduleinit()
+ if errstr != "" {
+ plugins[filepath] = &Plugin{
+ pluginpath: pluginpath,
+ err: errstr,
+ }
+ pluginsMu.Unlock()
+ return nil, errors.New(`plugin.Open("` + name + `"): ` + errstr)
+ }
// This function can be called from the init function of a plugin.
// Drop a placeholder in the map so subsequent opens can wait on it.
p := &Plugin{
@@ -153,7 +159,7 @@ func open(name string) (*Plugin, error) {
p := C.pluginLookup(h, (*C.char)(unsafe.Pointer(&cname[0])), &cErr)
if p == nil {
- return nil, errors.New("plugin.Open: could not find symbol " + symName + ": " + C.GoString(cErr))
+ return nil, errors.New(`plugin.Open("` + name + `"): could not find symbol ` + symName + `: ` + C.GoString(cErr))
}
valp := (*[2]unsafe.Pointer)(unsafe.Pointer(&sym))
if isFunc {
@@ -184,4 +190,4 @@ var (
)
// lastmoduleinit is defined in package runtime
-func lastmoduleinit() (pluginpath string, syms map[string]interface{}, mismatchpkg string)
+func lastmoduleinit() (pluginpath string, syms map[string]interface{}, errstr string)