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
暂时的修复办法:改用固定参数可正常运行