go: plugin: loading plugin leads to 'fatal error: invalid runtime symbol table' with some stdlib packages

Please answer these questions before submitting your issue. Thanks!

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

$ go version
go version go1.8beta1 darwin/amd64

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

$ go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/mccolljr/Documents/dev/go"
GORACE=""
GOROOT="/usr/local/Cellar/go/1.8beta1/libexec"
GOTOOLDIR="/usr/local/Cellar/go/1.8beta1/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/rg/pwv319qj009dkq19ryb8x3m00000gn/T/go-build046386885=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
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?

pg.go

attempted builds (same error for each): go build --buildmode=plugin pg.go go build --gcflags "-dynlink" --buildmode=plugin pg.go

package main

import (
	"log"
	"net/http"

	"html/template"
)

var Handler http.Handler

func init() {
	Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		p, err := template.ParseFiles("x.tpl")
		if err != nil {
			log.Fatalln(err)
		}

		p.ExecuteTemplate(w, "x.tpl", nil)
	})
}
x.tpl
TEST!
main.go

attempted builds (same error for each): go build main.go && ./main go build --gcflags "-dynlink" main.go && ./main

package main

import (
	"fmt"
	"net/http"
	"plugin"
)

func main() {
	p, err := plugin.Open("pg.so")

	if err != nil {
		panic(err)
	}

	sym, err := p.Lookup("Handler")

	if err != nil {
		panic(err)
	}

	fmt.Println("starting...")

	http.ListenAndServe(":8080", *(sym.(*http.Handler)))
}

note This program works correctly when you change pg.go to:

package main

import (
	"fmt"
	"net/http"
)

var Handler http.Handler

func init() {
	Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w, "TEST!")
	})
}

What did you expect to see?

terminal:

$ ./main
starting...

browser:

TEST!

What did you see instead?

runtime: invalid pc-encoded table f=gE#?? pc=0x40d92c1 targetpc=0x53dde9d tab=[0/0]0x0
	value=-1 until pc=0x40d9290
	value=0 until pc=0x40d9290
	value=0 until pc=0x40d9290
	value=228 until pc=0x40d92c1
	value=230 until pc=0x40d92c1
fatal error: invalid runtime symbol table

runtime stack:
invalid spdelta r; runtime.sizeclass int32; runtime.large bool } 0x405b9c0 0x5329fe5 0x3f3b4 -1
r; runtime.sizeclass int32; runtime.large bool }(0x100, 0x7fff5fbfef9800, 0x534336700)
	?:0 +0x12ce625

goroutine 1 [copystack]:
invalid spdelta gE#?? 0x40d9290 0x53dde9d 0x78c52 -1
gE#??(0xc4200ce64000, 0xa00, 0xa00, 0xc42006ed9800, 0xc420014db000)
	?:0 +0x1304c0d fp=0xc420137b6f sp=0xc420137b68

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
	/usr/local/Cellar/go/1.8beta1/libexec/src/runtime/asm_amd64.s:2184 +0x1
exit status 2

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 36 (16 by maintainers)

Commits related to this issue

Most upvoted comments

Those “invalid symbols table” errors in 1.8rc1 on linux were fixed in golang.org/cl/35190, and so they should be fixed by the coming 1.8rc2. If you have the time, please test against HEAD.

I’m keeping this bug open for darwin on 1.9.

Lots of meddling with the debugging in plugin.open eventually let me replicate the failure in a simpler plugin.

With stackDebug = 4, it very much looks like a non-pointer value in a stack pointer slot during copystack. The stack map itself looks reasonable. It very suspiciously always happens in plugin.open, the first function in the stack frame that comes from the other (host) module. No clear idea yet what’s happening. But now the plugin module does pass moduledataverify, which is nice.