New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/link: seg fault in shared buildmode from main package with exported variable #22566

Open
huawei-brice opened this Issue Nov 3, 2017 · 8 comments

Comments

Projects
None yet
4 participants
@huawei-brice

huawei-brice commented Nov 3, 2017

Please answer these questions before submitting your issue. Thanks!

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

go version go1.9.2 linux/amd64

Does this issue reproduce with the latest release?

Yes

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

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/brice/go"
GORACE=""
GOROOT="/usr/local/go-1.9.2"
GOTOOLDIR="/usr/local/go-1.9.2/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build769375432=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"

What did you do?

Create a simple source file:

package main

var Bar int

Build it with buildmode shared:

$ go build -buildmode=shared -linkshared b.go

What did you expect to see?

I expected it to build a shared library.

What did you see instead?

The linker crashes with a set fault:

$ go build -buildmode=shared -linkshared b.go
# command-line-arguments
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x10 pc=0x504d0e]

goroutine 1 [running]:
cmd/link/internal/ld.relocsym(0xc42053a000, 0xc420562bc8)
	/usr/local/go/src/cmd/link/internal/ld/data.go:639 +0x115e
cmd/link/internal/ld.(*Link).reloc(0xc42053a000)
	/usr/local/go/src/cmd/link/internal/ld/data.go:772 +0xbe
cmd/link/internal/ld.Main()
	/usr/local/go/src/cmd/link/internal/ld/main.go:221 +0xa1f
main.main()
	/usr/local/go/src/cmd/link/main.go:58 +0xac

Note: If the global variable is not exported (rename it to bar), then it builds as expected.

@ianlancetaylor ianlancetaylor changed the title from Linker seg fault in shared buildmode from main package with exported variable to cmd/link: seg fault in shared buildmode from main package with exported variable Nov 3, 2017

@ianlancetaylor

This comment has been minimized.

Contributor

ianlancetaylor commented Nov 3, 2017

I can't recreate this. What happens if you omit -linkshared? Since you are using -linkshared, have you run previous go install command that install a shared version of the runtime or standard library?

@huawei-brice

This comment has been minimized.

huawei-brice commented Nov 3, 2017

Yes, I have run go install -buildmode=shared std. Actually, if I omit -linkshared, I get something new:

/usr/local/go-1.9.2/pkg/tool/linux_amd64/link: cannot implicitly include runtime/cgo in a shared library

Since you can't reproduce, I will try this again with a clean environment and post back.

@huawei-brice

This comment has been minimized.

huawei-brice commented Nov 3, 2017

I just verified that I get the same result on a clean environment. Here is a Dockerfile I used:

FROM golang:latest

RUN mkdir -p /app

WORKDIR /app

ADD . /app

RUN go install -buildmode=shared std
RUN go build -buildmode=shared -linkshared b.go
@cherrymui

This comment has been minimized.

Contributor

cherrymui commented Nov 22, 2017

I can reproduce it on linux/amd64. The seg fault is from reading r.Sym.Sect.Name where the Sect is nil. r.Sym is "type.*int".

This seems to happen only when Bar is a builtin type (int here). It does not happen with

type T int
var Bar T
@bryanpkc

This comment has been minimized.

Contributor

bryanpkc commented Nov 22, 2017

#16632 is the same problem.

@bryanpkc

This comment has been minimized.

Contributor

bryanpkc commented Nov 22, 2017

This only happens when the package name is "main", which seems to cause the toolchain to believe that it is building in plugin mode, and start to generate a lot more stuff than it would otherwise. The relocation that is missing a section is in go.plugin.tabs:

go.plugin.tabs SRODATA size=8
        0x0000 00 00 00 00 00 00 00 00                          ........
        rel 0+4 t=5 type..namedata.Bar.+0
        rel 4+4 t=5 type.*int+0

If the package was something other than "main", the compiler proceeds in shared mode, and there is no relocation:

# command-line-arguments
go.cuinfo.producer.command-line-arguments SDWARFINFO dupok size=0
        0x0000 2d 64 79 6e 6c 69 6e 6b                          -dynlink
"".Bar SNOPTRBSS size=8
@bryanpkc

This comment has been minimized.

Contributor

bryanpkc commented Nov 22, 2017

I think both this and #16632 can be solved by moving basic types and import paths from the runtime package into the main package.

Edit: I realize that in general it's hard to tell whether a package will be the main package at compile time.

@ianlancetaylor

This comment has been minimized.

Contributor

ianlancetaylor commented Dec 6, 2017

My understanding is that this only happens when using -buildmode=shared with package main. So we still need to fix this, but it has a simple workaround. Moving to milestone Unplanned.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment