Go1.10 Plugin的bug

Posted by Edward.Yang on April 27, 2018

Go(1.10) Plugin 的bug

Go 的 plugin 包在 1.10 的版本中支持 Linux 和 Mac 操作系统,刚好有个项目可以用上,便抓紧试试手,拿着几个的demo跑了起来,似乎没有什么问题,但是当我测试到“可变参数”的时候,发现不能正常工作了…

上代码吧…


plug.go

package main

import (
	"fmt"
	"runtime"
)

type A struct {
}

func Main(args ...interface{}) {
	fmt.Println("[plugin] NumGoroutine:", runtime.NumGoroutine(), args)
}

编译成so

go build -buildmode=plugin ./plugin.go

main.go

package main

import (
	"plugin"
	"time"
)

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

	// Note that swapping these two lines makes the issue disappear
	go f(1)
	f(2)

	time.Sleep(time.Second)
}

运行 go run main.go的时候报错

[plugin] NumGoroutine: 2 [2]
runtime: bad pointer in frame plugin/unnamed-1af2f9e49ce9f7a74cfd724838e79534ecb20b50.Main at 0xc420050f78: 0x1
fatal error: invalid pointer found on stack

runtime stack:
runtime.throw(0x45e7148, 0x1e)
	/usr/local/go/src/runtime/panic.go:616 +0x81 fp=0x700003fae708 sp=0x700003fae6e8 pc=0x4527c51
runtime.adjustpointers(0xc420050f78, 0x700003fae800, 0x700003faebc0, 0x4656eb8, 0x465de80)
	/usr/local/go/src/runtime/stack.go:592 +0x23e fp=0x700003fae778 sp=0x700003fae708 pc=0x453b52e
runtime.adjustframe(0x700003faead0, 0x700003faebc0, 0x465de80)
	/usr/local/go/src/runtime/stack.go:663 +0x325 fp=0x700003fae830 sp=0x700003fae778 pc=0x453b875
runtime.gentraceback(0xffffffffffffffff, 0xffffffffffffffff, 0x0, 0xc420076780, 0x0, 0x0, 0x7fffffff, 0x45ea280, 0x700003faebc0, 0x0, ...)
	/usr/local/go/src/runtime/traceback.go:310 +0x12d3 fp=0x700003faeb38 sp=0x700003fae830 pc=0x4544533
runtime.copystack(0xc420076780, 0x1000, 0x700003faed01)
	/usr/local/go/src/runtime/stack.go:891 +0x26e fp=0x700003faecf0 sp=0x700003faeb38 pc=0x453c35e
runtime.newstack()
	/usr/local/go/src/runtime/stack.go:1063 +0x310 fp=0x700003faee80 sp=0x700003faecf0 pc=0x453c770
runtime.morestack()
	/usr/local/go/src/runtime/asm_amd64.s:480 +0x89 fp=0x700003faee88 sp=0x700003faee80 pc=0x454a3e9

goroutine 19 [copystack]:
runtime.(*mspan).nextFreeIndex(0x40b9ee0, 0x0)
	/usr/local/go/src/runtime/mbitmap.go:216 +0x16f fp=0xc420050b40 sp=0xc420050b38 pc=0x4510abf
runtime.(*mcache).nextFree(0x4116d90, 0x7, 0x0, 0x0, 0x0)
	/usr/local/go/src/runtime/malloc.go:548 +0x55 fp=0xc420050b98 sp=0xc420050b40 pc=0x450ea95
runtime.mallocgc(0x20, 0x0, 0x0, 0x0)
	/usr/local/go/src/runtime/malloc.go:710 +0x7e5 fp=0xc420050c38 sp=0xc420050b98 pc=0x450f485
runtime.growslice(0x4063260, 0x0, 0x0, 0x0, 0x16, 0x411c140, 0x0, 0x0)
	/usr/local/go/src/runtime/slice.go:172 +0x221 fp=0xc420050ca0 sp=0xc420050c38 pc=0x453a211
fmt.(*buffer).WriteString(...)
	/usr/local/go/src/fmt/print.go:82
fmt.(*fmt).padString(0xc4200d2040, 0x45e58fb, 0x16)
	/usr/local/go/src/fmt/format.go:110 +0x10b fp=0xc420050d28 sp=0xc420050ca0 pc=0x459f68b
fmt.(*fmt).fmt_s(0xc4200d2040, 0x45e58fb, 0x16)
	/usr/local/go/src/fmt/format.go:328 +0x61 fp=0xc420050d60 sp=0xc420050d28 pc=0x45a03c1
fmt.(*pp).fmtString(0xc4200d2000, 0x45e58fb, 0x16, 0xc400000076)
	/usr/local/go/src/fmt/print.go:437 +0x11f fp=0xc420050d98 sp=0xc420050d60 pc=0x45a361f
fmt.(*pp).printArg(0xc4200d2000, 0x4063120, 0x45f66b0, 0x76)
	/usr/local/go/src/fmt/print.go:671 +0x795 fp=0xc420050e10 sp=0xc420050d98 pc=0x45a55c5
fmt.(*pp).doPrintln(0xc4200d2000, 0xc420050f88, 0x3, 0x3)
	/usr/local/go/src/fmt/print.go:1146 +0x45 fp=0xc420050e80 sp=0xc420050e10 pc=0x45a7ff5
fmt.Fprintln(0x45f6da0, 0xc4200a4ea8, 0xc42003ef88, 0x3, 0x3, 0x4060060, 0x4505e01, 0xc4200d0000)
	/usr/local/go/src/fmt/print.go:254 +0x58 fp=0xc420050ee8 sp=0xc420050e80 pc=0x45a20c8
fmt.Println(0xc42003ef88, 0x3, 0x3, 0xc4200d0000, 0x0, 0x0)
	/usr/local/go/src/fmt/print.go:264 +0x5a fp=0xc420050f38 sp=0xc420050ee8 pc=0x45a21ca
plugin/unnamed-1af2f9e49ce9f7a74cfd724838e79534ecb20b50.Main(0xc420094200, 0x1, 0x1)
	/tmp/test/plugin.go:12 +0x10a fp=0xc420050fc8 sp=0xc420050f38 pc=0x45a856a
runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:2361 +0x1 fp=0xc420050fd0 sp=0xc420050fc8 pc=0x404c791
created by main.main
	/tmp/test/main.go:20 +0x128

goroutine 1 [sleep]:
runtime.gopark(0x407c488, 0x40bc980, 0x40774ad, 0x5, 0x13, 0x2)
	/usr/local/go/src/runtime/proc.go:291 +0x11a fp=0xc420065e60 sp=0xc420065e40 pc=0x402873a
runtime.goparkunlock(0x40bc980, 0x40774ad, 0x5, 0x13, 0x2)
	/usr/local/go/src/runtime/proc.go:297 +0x5e fp=0xc420065ea0 sp=0xc420065e60 pc=0x40287ee
time.Sleep(0x3b9aca00)
	/usr/local/go/src/runtime/time.go:102 +0x166 fp=0xc420065f00 sp=0xc420065ea0 pc=0x403f276
main.main()
	/tmp/test/main.go:23 +0x18d fp=0xc420065f88 sp=0xc420065f00 pc=0x4055bdd
runtime.main()
	/usr/local/go/src/runtime/proc.go:198 +0x212 fp=0xc420065fe0 sp=0xc420065f88 pc=0x40282f2
runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:2361 +0x1 fp=0xc420065fe8 sp=0xc420065fe0 pc=0x404c791

goroutine 2 [force gc (idle)]:
runtime.gopark(0x407c488, 0x40b9d60, 0x4078014, 0xf, 0x407c314, 0x1)
	/usr/local/go/src/runtime/proc.go:291 +0x11a fp=0xc420042768 sp=0xc420042748 pc=0x402873a
runtime.goparkunlock(0x40b9d60, 0x4078014, 0xf, 0x14, 0x1)
	/usr/local/go/src/runtime/proc.go:297 +0x5e fp=0xc4200427a8 sp=0xc420042768 pc=0x40287ee
runtime.forcegchelper()
	/usr/local/go/src/runtime/proc.go:248 +0xcc fp=0xc4200427e0 sp=0xc4200427a8 pc=0x402857c
runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:2361 +0x1 fp=0xc4200427e8 sp=0xc4200427e0 pc=0x404c791
created by runtime.init.4
	/usr/local/go/src/runtime/proc.go:237 +0x35

goroutine 3 [GC sweep wait]:
runtime.gopark(0x407c488, 0x40b9e40, 0x4077d1f, 0xd, 0x401c114, 0x1)
	/usr/local/go/src/runtime/proc.go:291 +0x11a fp=0xc420042f60 sp=0xc420042f40 pc=0x402873a
runtime.goparkunlock(0x40b9e40, 0x4077d1f, 0xd, 0x14, 0x1)
	/usr/local/go/src/runtime/proc.go:297 +0x5e fp=0xc420042fa0 sp=0xc420042f60 pc=0x40287ee
runtime.bgsweep(0xc420070000)
	/usr/local/go/src/runtime/mgcsweep.go:52 +0xa3 fp=0xc420042fd8 sp=0xc420042fa0 pc=0x401c1a3
runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:2361 +0x1 fp=0xc420042fe0 sp=0xc420042fd8 pc=0x404c791
created by runtime.gcenable
	/usr/local/go/src/runtime/mgc.go:216 +0x58

goroutine 18 [finalizer wait]:
runtime.gopark(0x45ea488, 0x40d5fd8, 0x45e4431, 0xe, 0x14, 0x1)
	/usr/local/go/src/runtime/proc.go:291 +0x126 fp=0xc42003e718 sp=0xc42003e6f8 pc=0x45295e6
runtime.goparkunlock(0x40d5fd8, 0x45e4431, 0xe, 0x14, 0x1)
	/usr/local/go/src/runtime/proc.go:297 +0x5e fp=0xc42003e758 sp=0xc42003e718 pc=0x452969e
runtime.runfinq()
	/usr/local/go/src/runtime/mfinal.go:175 +0xbe fp=0xc42003e7e0 sp=0xc42003e758 pc=0x4513fde
runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:2361 +0x1 fp=0xc42003e7e8 sp=0xc42003e7e0 pc=0x454c841
created by runtime.createfing
	/usr/local/go/src/runtime/mfinal.go:156 +0x66

goroutine 20 [syscall]:
runtime.notetsleepg(0x40bc9a0, 0x3b9aa84e, 0x0)
	/usr/local/go/src/runtime/lock_sema.go:280 +0x4b fp=0xc42003f760 sp=0xc42003f720 pc=0x400e85b
runtime.timerproc(0x40bc980)
	/usr/local/go/src/runtime/time.go:261 +0x2e7 fp=0xc42003f7d8 sp=0xc42003f760 pc=0x403f867
runtime.goexit()
	/usr/local/go/src/runtime/asm_amd64.s:2361 +0x1 fp=0xc42003f7e0 sp=0xc42003f7d8 pc=0x404c791
created by runtime.(*timersBucket).addtimerLocked
	/usr/local/go/src/runtime/time.go:160 +0x107
exit status 2

暂时的修复办法:改用固定参数可正常运行

issues: https://github.com/golang/go/issues/25118