go: plugin: add test (was encoding/asn1 error when using plugin)

Please answer these questions before submitting your issue. Thanks!

What version of Go are you using (go version)?

go version go1.8beta2 linux/amd64

What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/fsenart/projects"
GORACE=""
GOROOT="/home/fsenart/tools/go"
GOTOOLDIR="/home/fsenart/tools/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build746500890=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
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"

What did you do?

If possible, provide a recipe for reproducing the error. A complete runnable program is good. A link on play.golang.org is best.

// main.go

package main

import (
	"plugin"
	"reflect"
)

func main() {
	p, err := plugin.Open("plugin.so")
	if err != nil {
		panic(err)
	}
	f, err := p.Lookup("F")
	if err != nil {
		panic(err)
	}

	// f.(func())()
	reflect.ValueOf(f).Call(nil)
}
// plugin.go

package main

import "C"
import "net/http"

func F() {
	_, err := http.Get("https://example.com")
	if err != nil {
		panic(err)
	}
}
# Makefile

test: build
	@./main

build: clean
	@go build -buildmode=plugin -o plugin.so plugin.go
	@go build -o main main.go

clean:
	@rm -rf main *.so

What did you expect to see?

I don’t expect any panic to happen.

What did you see instead?

I see a panic happen.

panic: Get https://example.com: tls: failed to parse certificate from server: asn1: structure error: tags don't match (4 vs {class:0 tag:16 length:1242 isCompound:true}) {optional:false explicit:false application:false defaultValue:<nil> tag:<nil> stringType:0 timeType:0 set:false omitEmpty:false} RawContent @4

goroutine 1 [running]:
plugin/unnamed-4ad3198f73971e7223d350ce7ae956cd80d817d9.F()
	/home/fsenart/projects/src/github.com/alsanium/issue_asn1/plugin.go:9 +0x65
reflect.Value.call(0x4d3820, 0xc42000f728, 0x13, 0x4ef099, 0x4, 0x0, 0x0, 0x0, 0xc42000c2e0, 0x4d3820, ...)
	/home/fsenart/tools/go/src/reflect/value.go:434 +0x91f
reflect.Value.Call(0x4d3820, 0xc42000f728, 0x13, 0x0, 0x0, 0x0, 0xc42004df68, 0x4be551, 0x0)
	/home/fsenart/tools/go/src/reflect/value.go:302 +0xa4
main.main()
	/home/fsenart/projects/src/github.com/alsanium/issue_asn1/main.go:19 +0xed
Makefile:2: recipe for target 'test' failed

Observations

  • If I don’t use the reflect package, and instead make type assertion manually, then no error happens.

    f.(func())()
    // reflect.ValueOf(f).Call(nil)
    
  • If I don’t use the plugin package, then no error happens.

    package main
    
    import (
        "net/http"
        "reflect"
    )
    
    var f interface{} = func() {
        _, err := http.Get("https://example.com")
        if err != nil {
            panic(err)
        }
    }
    
    func main() {
        //f.(func())()
        reflect.ValueOf(f).Call(nil)
    }
    
    

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 1
  • Comments: 15 (6 by maintainers)

Commits related to this issue

Most upvoted comments

It was fixed by the fix to #18252.

But we should add a test for this in misc/cgo/testplugin.

@stefanahman we effectively use go plugins in this project and the issue is related to the fact that we have other imports than plugin in the referenced file (cf. above comment).

@bradfitz at the time I’ve opened the issue, I agree with you that the problem was very special and happen in rare cases and Go1.8Maybe milestone was ok. But considering my last comment, you must notice that as soon as any package is imported along with the plugin package then all SSL requests fail. Isn’t it a major issue to be fixed before the release of 1.8? Can you please reconsider the milestone, taking into account the new elements?

OK. THIS IS WEIRD.

After more investigation, it seems not even related to the reflect package.

The error happens if you import any package when using the plugin package. For example (plugin.go as above):

// main.go

package main

import (
	"fmt" // you can import any package (fails with fmt, log, json, etc.)
	"plugin"
)

func main() {
	fmt.Print() // dummy print for the import statement

	p, err := plugin.Open("plugin.so")
	if err != nil {
		panic(err)
	}
	f, err := p.Lookup("F")
	if err != nil {
		panic(err)
	}

	f.(func())()
}

PS: I don’t know what should be the issue title!

Can confirm that my issue has been resolved with v1.8rc1 😃 🎉

If we stopped the release train for every bug, we’d never ship.

Plugins are a new part of Go 1.8 anyway. Expect some rough edges. For instance, we disabled them entirely on Mac at the last second, and they don’t work on Windows. A few more bugs are expected. That’s what point releases are for.

Getting the same error using https://github.com/eawsy/aws-lambda-go-shim library. After more investigation and reading this thread, I noticed the plugin import in this file.