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
Closed

cmd/link: -buildmode=pie -linkshared generates incorrect code #25970

kiap opened this issue Jun 20, 2018 · 4 comments
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@kiap
Copy link

kiap 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 the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Jun 20, 2018
@ianlancetaylor ianlancetaylor added this to the Go1.11 milestone Jun 20, 2018
@ianlancetaylor
Copy link
Contributor

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
Copy link
Author

kiap 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 as completed Jun 20, 2018
@kiap kiap reopened this Jun 20, 2018
@mwhudson
Copy link
Contributor

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
Copy link

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

@golang golang locked and limited conversation to collaborators Jun 23, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

4 participants