Skip to content

attempt to support "go build -buildmode=plugin -linkshared". #45692

@crazycomputer

Description

@crazycomputer

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

$ go version
go version go1.14.12 linux/amd64

Does this issue reproduce with the latest release?

yes

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

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/root/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/mnt/d/wsl/01.Tools/golang/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/mnt/d/wsl/01.Tools/golang/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build174216265=/tmp/go-build -gno-record-gcc-switches"

What did you do?

first, use go install -buildmode=shared -linkshared std to build and install libstd.so
second, use go build -buildmode=plugin -linkshared plugin.go to build plugin.so
plugin.go:

package main
import "fmt"
func Print(){
	fmt.Println("plugin")
}

then, use go build -linkshared main.go to build main.go whit linkshared
main.go

package main

import (
	"log"
	"plugin"
)

func main() {
	p, err := plugin.Open("./plugin.so")
	if err != nil {
		log.Println(err)
	}
	f, err := p.Lookup("Print")
	if err != nil {
		log.Println(err)
	}
	f.(func())()
}

then I run main.

What did you expect to see?

main process run and print "plugin"

What did you see instead?

./main
SIGTRAP: trace trap
PC=0x7fb9410a81c1 m=0 sigcode=128

goroutine 0 [idle]:
runtime: unknown pc 0x7fb9410a81c1
stack: frame={sp:0x7ffe9713c240, fp:0x0} stack=[0x7ffe9693d8a0,0x7ffe9713c8e0)
00007ffe9713c140:  00007fb9410a64e0  00007ffe9713c230 
00007ffe9713c150:  0000000000000001  00007fb94383c548 
00007ffe9713c160:  0000000000000006  00000000000047a8 
00007ffe9713c170:  0000000000000ab0  0000000000000000 
00007ffe9713c180:  0000000000001000  0000000064cd305f 
00007ffe9713c190:  000056530156bc08  00007ffe9713c358 
00007ffe9713c1a0:  00007fb9410a68cc  00007ffe9713c230 
00007ffe9713c1b0:  00007ffe9713c240  00007fb9438491e9 
00007ffe9713c1c0:  0000000000000001  0000000000000000 
00007ffe9713c1d0:  0000000000000009  0000000000000000 
00007ffe9713c1e0:  0000000000000001  000056530156b8a0 
00007ffe9713c1f0:  0000000000000004  0000000000000000 
00007ffe9713c200:  000056530156b8a0  000056530156bc08 
00007ffe9713c210:  0000000000000000  0000000000000000 
00007ffe9713c220:  0000000000000000  0000000000000001 
00007ffe9713c230:  00000000ffffffff  00000000000037a8 
00007ffe9713c240: <00007fb9410a81ec  00007fb94384eb8a 
00007ffe9713c250:  0000000000000000  0000000000000001 
00007ffe9713c260:  00007ffe9713c9f8  00007ffe9713ca08 
00007ffe9713c270:  000056530156b8a0  00007fb94384ec91 
00007ffe9713c280:  78f25a33371354c3  00007ffe9713c5e0 
00007ffe9713c290:  00007ffe9713c480  fffffffffffffff0 
00007ffe9713c2a0:  0000000000000001  0000000000000006 
00007ffe9713c2b0:  000056530156b8a0  00007fb941013915 
00007ffe9713c2c0:  0000000000000000  00007ffe9713c4c0 
00007ffe9713c2d0:  00007fb9438522c0  00007ffe9713c430 
00007ffe9713c2e0:  4c576d5352587769  0000000000000000 
00007ffe9713c2f0:  0000000000000002  0000003200000008 
00007ffe9713c300:  0000000000000000  0000000000000000 
00007ffe9713c310:  0000000000000000  000000770000007c 
00007ffe9713c320:  0000005b0000006e  0000000000000000 
00007ffe9713c330:  00007fb9410a6000  0000000000000006 
runtime: unknown pc 0x7fb9410a81c1
stack: frame={sp:0x7ffe9713c240, fp:0x0} stack=[0x7ffe9693d8a0,0x7ffe9713c8e0)
00007ffe9713c140:  00007fb9410a64e0  00007ffe9713c230 
00007ffe9713c150:  0000000000000001  00007fb94383c548 
00007ffe9713c160:  0000000000000006  00000000000047a8 
00007ffe9713c170:  0000000000000ab0  0000000000000000 
00007ffe9713c180:  0000000000001000  0000000064cd305f 
00007ffe9713c190:  000056530156bc08  00007ffe9713c358 
00007ffe9713c1a0:  00007fb9410a68cc  00007ffe9713c230 
00007ffe9713c1b0:  00007ffe9713c240  00007fb9438491e9 
00007ffe9713c1c0:  0000000000000001  0000000000000000 
00007ffe9713c1d0:  0000000000000009  0000000000000000 
00007ffe9713c1e0:  0000000000000001  000056530156b8a0 
00007ffe9713c1f0:  0000000000000004  0000000000000000 
00007ffe9713c200:  000056530156b8a0  000056530156bc08 
00007ffe9713c210:  0000000000000000  0000000000000000 
00007ffe9713c220:  0000000000000000  0000000000000001 
00007ffe9713c230:  00000000ffffffff  00000000000037a8 
00007ffe9713c240: <00007fb9410a81ec  00007fb94384eb8a 
00007ffe9713c250:  0000000000000000  0000000000000001 
00007ffe9713c260:  00007ffe9713c9f8  00007ffe9713ca08 
00007ffe9713c270:  000056530156b8a0  00007fb94384ec91 
00007ffe9713c280:  78f25a33371354c3  00007ffe9713c5e0 
00007ffe9713c290:  00007ffe9713c480  fffffffffffffff0 
00007ffe9713c2a0:  0000000000000001  0000000000000006 
00007ffe9713c2b0:  000056530156b8a0  00007fb941013915 
00007ffe9713c2c0:  0000000000000000  00007ffe9713c4c0 
00007ffe9713c2d0:  00007fb9438522c0  00007ffe9713c430 
00007ffe9713c2e0:  4c576d5352587769  0000000000000000 
00007ffe9713c2f0:  0000000000000002  0000003200000008 
00007ffe9713c300:  0000000000000000  0000000000000000 
00007ffe9713c310:  0000000000000000  000000770000007c 
00007ffe9713c320:  0000005b0000006e  0000000000000000 
00007ffe9713c330:  00007fb9410a6000  0000000000000006 

goroutine 1 [syscall]:
runtime.cgocall(0x7fb9423d65f0, 0xc000362c40, 0xc000432018)
	/mnt/d/wsl/01.Tools/golang/1.16.3/go/src/runtime/cgocall.go:154 +0x65 fp=0xc000362c10 sp=0xc000362bd8 pc=0x7fb941c292c5
plugin._Cfunc_pluginOpen(0xc000438000, 0xc000432018, 0x0)
	_cgo_gotypes.go:76 +0x4e fp=0xc000362c40 sp=0xc000362c10 pc=0x7fb9423b386e
plugin.open.func1(0xc000438000, 0x1001, 0x1001, 0xc000432018, 0x7fb943832ae0)
	/mnt/d/wsl/01.Tools/golang/1.16.3/go/src/plugin/plugin_dlopen.go:64 +0x7d fp=0xc000362c70 sp=0xc000362c40 pc=0x7fb9423b4c3d
plugin.open(0x5653005ca015, 0xb, 0xc000000300, 0x300000002, 0xc000000300)
	/mnt/d/wsl/01.Tools/golang/1.16.3/go/src/plugin/plugin_dlopen.go:64 +0x34e fp=0xc000362ee8 sp=0xc000362c70 pc=0x7fb9423b3cee
plugin.Open(...)
	/mnt/d/wsl/01.Tools/golang/1.16.3/go/src/plugin/plugin.go:32
()
	/mnt/d/wsl/02.Code/01.GOPATH/src/plugindemo/main/main.go:9 +0x4a fp=0xc000362f88 sp=0xc000362ee8 pc=0x5653005c922a
runtime.main()
	/mnt/d/wsl/01.Tools/golang/1.16.3/go/src/runtime/proc.go:225 +0x2aa fp=0xc000362fe0 sp=0xc000362f88 pc=0x7fb941c72aca
runtime.goexit()
	/mnt/d/wsl/01.Tools/golang/1.16.3/go/src/runtime/asm_amd64.s:1371 +0x1 fp=0xc000362fe8 sp=0xc000362fe0 pc=0x7fb941cb3061

rax    0x0
rbx    0x7fb9410aa7b0
rcx    0x7ffe9713ca08
rdx    0x7ffe9713ca08
rdi    0x7fb9410ab040
rsi    0x7ffe9713c9f8
rbp    0x1
rsp    0x7ffe9713c240
r8     0x0
r9     0x1
r10    0x0
r11    0x7fb94109bbe0
r12    0x7ffe9713c9f8
r13    0x7ffe9713ca08
r14    0x7fb9410aa7b8
r15    0x0
rip    0x7fb9410a81c1
rflags 0x202
cs     0x33
fs     0x0
gs     0x0

then I use objdump -D plugin.so , I found that the function runtime.addmoduledata is not in plt of plugin.so, when go.link.addmoduledata is called in dllopen, it jumped to a wrong address.
image

If I can add runtime.addmoduledata to plt in plugin.so, maybe I can use plugin.Open to open the plugin.so success.so,I modified the linker in toolchain. then this mistake is fixed.

image
image

Then, when I run the main. it returns an error: "plugin was built with a different version of package". I found the pkghash of the pkgs in libstd.so is blank in plugin. I modifier the linker:

image

It will not generate pkghash of the pkg in libstd.so to plugin.so in linktime.

After these modification,the main process runs success,and I tried some more complex plugin,it works well.
But I can't judge are there any other risk after these modification. I want to use it in production environment. Can anyone help me?

--

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions