cmd/go: TestCgoConsistentResults fails on s390x with gcc 6 #16780

Closed
mwhudson opened this Issue Aug 17, 2016 · 6 comments

Comments

Projects
None yet
3 participants
Contributor

mwhudson commented Aug 17, 2016

Please answer these questions before submitting your issue. Thanks!

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

go version devel +17eee31 Wed Aug 17 23:28:20 2016 +0000 linux/s390x

but it happens with 1.7 too (see https://launchpadlibrarian.net/279519590/buildlog_ubuntu-yakkety-s390x.golang-1.7_1.7-2ubuntu1_BUILDING.txt.gz)

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

Ubuntu 16.10, s390x

  1. What did you do?

go test cmd/go -run TestCgoConsistentResults

  1. What did you expect to see?

ok cmd/go 2.538s

  1. What did you see instead?
--- FAIL: TestCgoConsistentResults (0.66s)
        go_test.go:244: running testgo [build -o /tmp/gotest566723264/cgotest1 cgotest]
        go_test.go:244: running testgo [build -x -o /tmp/gotest566723264/cgotest2 cgotest]
        go_test.go:263: standard error:
        go_test.go:264: WORK=/tmp/go-build196067513
                mkdir -p $WORK/cgotest/_obj/
                mkdir -p $WORK/
                cd /home/mwh/go/src/cmd/go/testdata/src/cgotest
                CGO_LDFLAGS="-g" "-O2" /home/mwh/go/pkg/tool/linux_s390x/cgo -objdir $WORK/cgotest/_obj/ -importpath cgotest -- -I $WORK/cgotest/_obj/ m.go
                cd $WORK
                gcc -fdebug-prefix-map=a=b -c trivial.c
                gcc -gno-record-gcc-switches -c trivial.c
                cd /home/mwh/go/src/cmd/go/testdata/src/cgotest
                gcc -I . -fPIC -m64 -march=z196 -pthread -fmessage-length=0 -fdebug-prefix-map=$WORK=/tmp/go-build -gno-record-gcc-switches -I $WORK/cgotest/_obj/ -g -O2 -o $WORK/cgotest/_obj/_cgo_main.o -c $WORK/cgotest/_obj/_cgo_main.c
                gcc -I . -fPIC -m64 -march=z196 -pthread -fmessage-length=0 -fdebug-prefix-map=$WORK=/tmp/go-build -gno-record-gcc-switches -I $WORK/cgotest/_obj/ -g -O2 -o $WORK/cgotest/_obj/_cgo_export.o -c $WORK/cgotest/_obj/_cgo_export.c
                gcc -I . -fPIC -m64 -march=z196 -pthread -fmessage-length=0 -fdebug-prefix-map=$WORK=/tmp/go-build -gno-record-gcc-switches -I $WORK/cgotest/_obj/ -g -O2 -o $WORK/cgotest/_obj/m.cgo2.o -c $WORK/cgotest/_obj/m.cgo2.c
                gcc -I . -fPIC -m64 -march=z196 -pthread -fmessage-length=0 -fdebug-prefix-map=$WORK=/tmp/go-build -gno-record-gcc-switches -o $WORK/cgotest/_obj/_cgo_.o $WORK/cgotest/_obj/_cgo_main.o $WORK/cgotest/_obj/_cgo_export.o $WORK/cgotest/_obj/m.cgo2.o -g -O2
                /home/mwh/go/pkg/tool/linux_s390x/cgo -objdir $WORK/cgotest/_obj/ -dynpackage cgotest -dynimport $WORK/cgotest/_obj/_cgo_.o -dynout $WORK/cgotest/_obj/_cgo_import.go
                cd $WORK
                gcc -no-pie -c trivial.c
                cd /home/mwh/go/src/cmd/go/testdata/src/cgotest
                gcc -I . -fPIC -m64 -march=z196 -pthread -fmessage-length=0 -fdebug-prefix-map=$WORK=/tmp/go-build -gno-record-gcc-switches -o $WORK/cgotest/_obj/_all.o $WORK/cgotest/_obj/_cgo_export.o $WORK/cgotest/_obj/m.cgo2.o -g -O2 -Wl,-r -nostdlib -no-pie -Wl,--build-id=none
                /home/mwh/go/pkg/tool/linux_s390x/compile -o $WORK/cgotest.a -trimpath $WORK -p cgotest -buildid 48821ae85cbf574dd21896d65f343fccedd4a562 -D _/home/mwh/go/src/cmd/go/testdata/src/cgotest -I $WORK -pack $WORK/cgotest/_obj/_cgo_gotypes.go $WORK/cgotest/_obj/m.cgo1.go $WORK/cgotest/_obj/_cgo_import.go
                pack r $WORK/cgotest.a $WORK/cgotest/_obj/_all.o # internal
                mkdir -p /tmp/gotest566723264/
                mv $WORK/cgotest.a /tmp/gotest566723264/cgotest2

        go_test.go:2819: building cgotest twice did not produce the same output
FAIL
FAIL    cmd/go  2.574s

It passes if I set CC=gcc-5.

Contributor

mwhudson commented Aug 17, 2016

The difference in the files is because the build path is ending up in the symbol table of the _all.o files:

mwh@DEVAC02:~/t$ diff -u <(readelf -s a/_all.o) <(readelf -s b/_all.o)
--- /dev/fd/63  2016-08-18 02:51:40.567866520 +0300
+++ /dev/fd/62  2016-08-18 02:51:40.567866520 +0300
@@ -12,7 +12,7 @@
      8: 0000000000000000     0 SECTION LOCAL  DEFAULT   10 
      9: 0000000000000000     0 SECTION LOCAL  DEFAULT   11 
     10: 0000000000000000     0 SECTION LOCAL  DEFAULT   12 
-    11: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS /tmp/go-build537256534/cg
+    11: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS /tmp/go-build491807700/cg
     12: 000000000000000e     0 NOTYPE  LOCAL  DEFAULT   12 .LASF15
     13: 0000000000000078     0 NOTYPE  LOCAL  DEFAULT   12 .LASF16
     14: 0000000000000041     0 NOTYPE  LOCAL  DEFAULT   12 .LASF0
@@ -30,7 +30,7 @@
     26: 00000000000000bd     0 NOTYPE  LOCAL  DEFAULT   12 .LASF12
     27: 000000000000006a     0 NOTYPE  LOCAL  DEFAULT   12 .LASF13
     28: 0000000000000032     0 NOTYPE  LOCAL  DEFAULT   12 .LASF14
-    29: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS /tmp/go-build537256534/cg
+    29: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS /tmp/go-build491807700/cg
     30: 000000000000018d     0 NOTYPE  LOCAL  DEFAULT   12 .LASF10
     31: 000000000000011b     0 NOTYPE  LOCAL  DEFAULT   12 .LASF11
     32: 000000000000017f     0 NOTYPE  LOCAL  DEFAULT   12 .LASF0

(confirmed by diffing xxd output that this is the only difference). Probably a gcc issue? Paging @ianlancetaylor

Contributor

ianlancetaylor commented Aug 18, 2016

That was supposed to have been fixed by the change to cmd/link in https://golang.org/cl/19363. I don't know why there would be anything s390x specific here.

Can you show the diff with readelf -s --wide? (Always use --wide with readelf, I consider the fact that --wide is not the default to be a bug in readelf.)

Contributor

mwhudson commented Aug 18, 2016

Heh, I have readelf aliased to readelf --wide locally, which means I tend to forget it on remote machines...

mwh@DEVAC02:~/t$ diff -u <(readelf --wide -s a/_all.o) <(readelf --wide -s b/_all.o)
--- /dev/fd/63  2016-08-18 11:19:56.588796246 +0300
+++ /dev/fd/62  2016-08-18 11:19:56.588796246 +0300
@@ -12,7 +12,7 @@
      8: 0000000000000000     0 SECTION LOCAL  DEFAULT   10 
      9: 0000000000000000     0 SECTION LOCAL  DEFAULT   11 
     10: 0000000000000000     0 SECTION LOCAL  DEFAULT   12 
-    11: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS /tmp/go-build537256534/cgotest/_obj/_cgo_export.o
+    11: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS /tmp/go-build491807700/cgotest/_obj/_cgo_export.o
     12: 000000000000000e     0 NOTYPE  LOCAL  DEFAULT   12 .LASF15
     13: 0000000000000078     0 NOTYPE  LOCAL  DEFAULT   12 .LASF16
     14: 0000000000000041     0 NOTYPE  LOCAL  DEFAULT   12 .LASF0
@@ -30,7 +30,7 @@
     26: 00000000000000bd     0 NOTYPE  LOCAL  DEFAULT   12 .LASF12
     27: 000000000000006a     0 NOTYPE  LOCAL  DEFAULT   12 .LASF13
     28: 0000000000000032     0 NOTYPE  LOCAL  DEFAULT   12 .LASF14
-    29: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS /tmp/go-build537256534/cgotest/_obj/m.cgo2.o
+    29: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS /tmp/go-build491807700/cgotest/_obj/m.cgo2.o
     30: 000000000000018d     0 NOTYPE  LOCAL  DEFAULT   12 .LASF10
     31: 000000000000011b     0 NOTYPE  LOCAL  DEFAULT   12 .LASF11
     32: 000000000000017f     0 NOTYPE  LOCAL  DEFAULT   12 .LASF0

I agree it's deeply odd that this only happens on s390x (and only with gcc 6). It could be a problem in the set up of the gcc-6 package in Ubuntu I guess.

Contributor

mwhudson commented Aug 23, 2016

So the CL @ianlancetaylor referenced has a hint to what is going on here:

Add an empty NAME symbol to the ELF .symtab. GNU ld will add a NAME
symbol when one is not present; including one of our own prevents it
from adding a reference to the link tempdir.

What has changed between gcc-5 and gcc-6 (and apparently only on s390x) is that gcc no longer adds a file symbol when compiling a file:

mwh@DEVAC02:~/foo$ echo 'int main(int argc, char* argv) { return 0; }' > trivial.c
mwh@DEVAC02:~/foo$ gcc-6 -c trivial.c -o trivial.o
mwh@DEVAC02:~/foo$ readelf --wide -s trivial.o | grep FILE
mwh@DEVAC02:~/foo$ gcc-5 -c trivial.c -o trivial.o
mwh@DEVAC02:~/foo$ readelf --wide -s trivial.o | grep FILE
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS trivial.c

I don't know if this counts as a gcc bug or something we should be trying to work around or what. I'll ask doko I guess.

Contributor

ianlancetaylor commented Aug 23, 2016

It's because the function s390_asm_file_start in gcc/config/s390/s390.c does not call default_file_start. The function was added here: https://gcc.gnu.org/ml/gcc-patches/2015-09/msg01956.html .

Contributor

mwhudson commented Aug 23, 2016

This has now been fixed in gcc tip, nothing to do in Go, so closing.

@mwhudson mwhudson closed this Aug 23, 2016

@gopherbot gopherbot locked and limited conversation to collaborators Aug 23, 2017

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