go: plugin: syscall.Mmap panic: assignment to entry in nil map

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

$ go version
go version go1.16 linux/amd64

Does this issue reproduce with the latest release?

Yes, only using plugins. But it works with go1.15.8 (with plugins or not).

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

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/oszika/.cache/go-build"
GOENV="/home/oszika/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/oszika/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/oszika/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/lib/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.16"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/tmp/example/go.mod"
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-build1397047588=/tmp/go-build -gno-record-gcc-switches"

What did you do?

I build a plugin, that calls raftboltdb.NewBoltStore. Then I use this plugin.

Plugin: /tmp/example/plugin/main.go:

package main

import (
        "log"

        raftboltdb "github.com/hashicorp/raft-boltdb"
)

var Init = func() {
        log.Println(raftboltdb.NewBoltStore("/tmp/raft.db"))
}

func main() {}

Build:

go build -buildmode=plugin -o plugin.so .

Main file: /tmp/example/main.go:

package main

import (
        "log"
        "plugin"
)

func main() {
        p, err := plugin.Open("plugin/plugin.so")
        if err != nil {
                log.Fatal(err)
        }
        s, err := p.Lookup("Init")
        if err != nil {
                log.Fatal(err)
        }

        f := *s.(*func())
        f()
}

Run:

go run main.go

I’ll try to call Init() in the main of plugin.go directly. There is no problem. It seems wrong only for plugins.

What did you expect to see?

No panic, no error.

What did you see instead?

panic: assignment to entry in nil map

goroutine 1 [running]: syscall.(*mmapper).Mmap(0x7fe6d5321aa0, 0x6, 0x0, 0x8000, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, …) /usr/lib/go/src/syscall/syscall_unix.go:75 +0x173 syscall.Mmap(…) /usr/lib/go/src/syscall/syscall_linux.go:1230 github.com/boltdb/bolt.mmap(0xc00000c1e0, 0x8000, 0x0, 0x0) /home/oszika/go/pkg/mod/github.com/boltdb/bolt@v1.3.1/bolt_unix.go:50 +0xa5 github.com/boltdb/bolt.(*DB).mmap(0xc00000c1e0, 0x0, 0x0, 0x0) /home/oszika/go/pkg/mod/github.com/boltdb/bolt@v1.3.1/db.go:277 +0x245 github.com/boltdb/bolt.Open(0x7fe6d50f560d, 0xc, 0xc000000180, 0x7fe6d538e7a0, 0x5f05c0, 0x5fdb80, 0x0) /home/oszika/go/pkg/mod/github.com/boltdb/bolt@v1.3.1/db.go:230 +0x305 github.com/hashicorp/raft-boltdb.New(0x7fe6d50f560d, 0xc, 0x0, 0xc00012e000, 0xc00012e000, 0x0, 0x0) /home/oszika/go/pkg/mod/github.com/hashicorp/raft-boltdb@v0.0.0-20191021154308-4207f1bf0617/bolt_store.go:66 +0x4d github.com/hashicorp/raft-boltdb.NewBoltStore(…) /home/oszika/go/pkg/mod/github.com/hashicorp/raft-boltdb@v0.0.0-20191021154308-4207f1bf0617/bolt_store.go:60 example/plugin.glob…func1() /tmp/example/plugin/main.go:10 +0x4a main.main() /tmp/example/main.go:19 +0x176 exit status 2

Workaround

Call syscall.Mmap in the main program.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 16 (6 by maintainers)

Most upvoted comments

Thank you, but that is not what I was suggesting.

I have a theory that the internal structure for tracking mmap allocations in the syscall package is not correctly initalised because it is not used in the main program. If you call syscall.Mmap from your main program, not the plugin, then it will initalise the correct internal structures in the syscall package (or to be more specific, stop the linker stripping them out), and this may work around the problem.