diff options
Diffstat (limited to 'src/plugin/plugin_dlopen.go')
| -rw-r--r-- | src/plugin/plugin_dlopen.go | 26 |
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) |
