Skip to content
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: -buildmode=pie -linkshared generates incorrect code #25970

Closed
kiap opened this issue Jun 20, 2018 · 4 comments

Comments

Projects
None yet
4 participants
@kiap
Copy link

commented Jun 20, 2018

Please answer these questions before submitting your issue. Thanks!

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

go version go1.10.3 linux/amd64

Does this issue reproduce with the latest release?

Yes, even on Master and all branches since 1.10 (was working properly on 1.10)

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

CentOS Linux release 7.5.1804 (Core)
libgcc-4.8.5-28.el7_5.1.i686
libgcc-4.8.5-28.el7_5.1.x86_64
gcc-c++-4.8.5-28.el7_5.1.x86_64
gcc-4.8.5-28.el7_5.1.x86_64

go env

GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/usr/src/dev"
GORACE=""
GOROOT="/usr/src/go"
GOTMPDIR=""
GOTOOLDIR="/usr/src/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
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"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build542819085=/tmp/go-build -gno-record-gcc-switches"

What did you do?

prog1: (simple)
https://play.golang.org/p/GdPKpqF4jx1

prog2: (with goroutines)
https://play.golang.org/p/Unoy--GQG87

prog3: (simple with standard package)
https://play.golang.org/p/rY3RgWfkWAo

go install -v -ldflags '-s -w' -gcflags '-trimpath /usr/src/go' -buildmode=shared -linkshared -pkgdir /usr/src/lib std

go install -v -ldflags '-s -w' -gcflags '-trimpath /usr/src/dev' -buildmode=pie -linkshared -pkgdir /usr/src/lib prog

replace prog with prog1 prog2 or prog3

ATTENTION:
If you compile normally without buildmode=shared -linkshared then it works properly like this

go install -v -ldflags '-s -w' -gcflags '-trimpath /usr/src/dev' -buildmode=pie prog

What did you expect to see?

prog1:

Object 0
Value 46
This is a test 3.141950
itest
finish
linux amd64 4
ptr p: 0xc4200101f0
ptr *p: ciao
s: ciao
&s: 0xc4200101f0

prog2:

50000005000000
0.005969
00100010
50000005000000
0.011546
bin/prog2
9
512

prog3:

[51 165 23 125 0 65 187 12 113 16 144 21 229 235 205 79 65 224 131 252 155 202 71 22 3 69 114 106 183 8 241 38 249 5 250 155 150 232 17 89 70 23 120 67 38 29 206 29]

What did you see instead?

prog1:

Object 0
Value 46
This is a test 3.141950
itest
finish
linux amd64 4
ptr p: 0xc4200101f0
ptr *p: ciao
s: ciao
&s: 0xc4200101f0

prog2:

fatal error: makechan: invalid channel element type

goroutine 1 [running]:
runtime.throw(0x7f4c3e856a16, 0x26)
/usr/src/go/src/runtime/panic.go:616 +0x83 fp=0xc420365e10 sp=0xc420365df0 pc=0x7f4c3e224e13
runtime.makechan(0x5608292e1020, 0x2, 0x7f4c3f282560)
/usr/src/go/src/runtime/chan.go:75 +0x267 fp=0xc420365e50 sp=0xc420365e10 pc=0x7f4c3e1f48c7
main.main()
src/prog2/main.go:25 +0x72 fp=0xc420365f88 sp=0xc420365e50 pc=0x5608290def42
runtime.main()
/usr/src/go/src/runtime/proc.go:198 +0x24f fp=0xc420365fe0 sp=0xc420365f88 pc=0x7f4c3e2275bf
runtime.goexit()
/usr/src/go/src/runtime/asm_amd64.s:2361 +0x1 fp=0xc420365fe8 sp=0xc420365fe0 pc=0x7f4c3e25c7c1

prog3:

runtime: out of memory: cannot allocate 7205794687101042688-byte block (3899392 in use)
fatal error: out of memory

runtime stack:
runtime.throw(0x7f5ba58aeee3, 0xd)
/usr/src/go/src/runtime/panic.go:616 +0x83
runtime.largeAlloc(0x64002017090d8b48, 0x7f5ba52c0101, 0x7f5ba6e6f000)
/usr/src/go/src/runtime/malloc.go:828 +0x112
runtime.mallocgc.func1()
/usr/src/go/src/runtime/malloc.go:721 +0x48
runtime.systemstack(0x7f5b00000000)
/usr/src/go/src/runtime/asm_amd64.s:409 +0x72
runtime.mstart()
/usr/src/go/src/runtime/proc.go:1175

goroutine 1 [running]:
runtime.systemstack_switch()
/usr/src/go/src/runtime/asm_amd64.s:363 fp=0xc420365e48 sp=0xc420365e40 pc=0x7f5ba52c7b50
runtime.mallocgc(0x64002017090d8b48, 0x55f0b34418a0, 0x7f5ba5f77101, 0xc420374060)
/usr/src/go/src/runtime/malloc.go:720 +0x909 fp=0xc420365ee8 sp=0xc420365e48 pc=0x7f5ba5273fa9
runtime.convT2Eslice(0x55f0b34418a0, 0xc420365f60, 0x55f0b3441c02, 0xe)
/usr/src/go/src/runtime/iface.go:384 +0x6b fp=0xc420365f18 sp=0xc420365ee8 pc=0x7f5ba527175b
main.main()
src/prog3/main.go:17 +0x91 fp=0xc420365f88 sp=0xc420365f18 pc=0x55f0b3441a71
runtime.main()
/usr/src/go/src/runtime/proc.go:198 +0x24f fp=0xc420365fe0 sp=0xc420365f88 pc=0x7f5ba52955bf
runtime.goexit()
/usr/src/go/src/runtime/asm_amd64.s:2361 +0x1 fp=0xc420365fe8 sp=0xc420365fe0 pc=0x7f5ba52ca7c1

@ianlancetaylor ianlancetaylor changed the title cmd/go: Compiling with shared library results in Runtime Out of Memory Error cmd/link: -buildmode=pie -linkshared generates incorrect code Jun 20, 2018

@ianlancetaylor ianlancetaylor added this to the Go1.11 milestone Jun 20, 2018

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

commented Jun 20, 2018

The problem seems to be due to the combination of -buildmode=pie and -linkshared. Simple reproduction:

foo.go:

package main

func main() {
	c := make(chan int)
	_ = c
}

Instructions:

go install -buildmode=shared std
go build -buildmode=pie -linkshared foo.go
./foo

When I do that on amd64 GNU/Linux I get

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x30 pc=0x7fd9a1dd1398]

goroutine 1 [running]:
main.main()
	/home/iant/foo.go:4 +0x38

Part of the main.main function looks like this, as printed by gdb while executing:

   0x00005555555551ef <+31>:	mov    0x200e0a(%rip),%rax        # 0x555555756000
   0x00005555555551f6 <+38>:	mov    %rax,(%rsp)
   0x00005555555551fa <+42>:	movq   $0x0,0x8(%rsp)
   0x0000555555555203 <+51>:	callq  0x555555555080 <runtime.makechan@plt>

The load at <+31> should be loading the type descriptor to pass to makechan. Instead it gets the value 0. This leads directly to the crash.

CC @mwhudson

@kiap

This comment has been minimized.

Copy link
Author

commented Jun 20, 2018

Just need to add that I tried All versions since 1.9.6 on CentOS 6 and CentOS 7 latest releases and even previous code do not work when pie and linkshared are present, I believe an update to CentOS gcc or relevant libraries caused this, as it was working just fine, even previously working releases do not work with current updates on CentOS 6 and CentOS 7

It is not isolated to channels or goroutine with any large program you can reproduce this problem

in example: https://play.golang.org/p/nZcaXvMBeiE

@kiap kiap closed this Jun 20, 2018

@kiap kiap reopened this Jun 20, 2018

@mwhudson

This comment has been minimized.

Copy link
Contributor

commented Jun 20, 2018

The problem is that we take this conditional: https://github.com/golang/go/blob/master/src/cmd/link/internal/ld/symtab.go#L371

None of this coalescing of multiple symbols into foo.* symbols is valid when dynamically linking go code.

@gopherbot

This comment has been minimized.

Copy link

commented Jun 20, 2018

Change https://golang.org/cl/120235 mentions this issue: cmd/link: never coalesce type descriptors when dynamically linking Go

@gopherbot gopherbot closed this in d6a27e8 Jun 23, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.