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: 386 and amd64 hosts produce different 386 binaries #22193

Open
starius opened this Issue Oct 10, 2017 · 10 comments

Comments

Projects
None yet
4 participants
@starius

starius commented Oct 10, 2017

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

1.9.1

Does this issue reproduce with the latest release?

Yes

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

Host: Linux amd64 and 386, Darwin amd64.
Target: {amd64, 386} {Linux, Darwin, Windows}.

What did you do?

I built the following program (located in $GOPATH/src/test/main.go):

package main

import "os"
import "os/signal"

func main() {
    sig := make(chan os.Signal, 10)
    signal.Stop(sig)
}

with the following command:

GOOS=linux GOARCH=386 go install -a -tags netgo -ldflags='-s -w' test

on two host machines: Linux amd64 and Linux 386.
The produced binaries were different.

I wrote a script that installs Go 1.4 which installs Go 1.9.1 which installs another Go 1.9.1 (as suggested on the IRC channel) which builds the program.

Results:

host=linux_amd64
* 6764b1c25110b5050739ea420d21707fe7f60c8f0f60e5aa0edc16a9ba1ed958  /tmp/gopath/bin/darwin_386/test
  099d1ea0f08c12961871062175ed1eb0f08a9c3711a04ae7b065ed464d0f7c4e  /tmp/gopath/bin/darwin_amd64/test
* 85b7da6f6627c34e50ba1801380ad28dad07cb8409c13afef78f02c0c4f3cc7d  /tmp/gopath/bin/linux_386/test
  0f56ffbe56fb47d76e34a174ca9a16e948ed31d0f1966d3ad3a9e4413bc21288  /tmp/gopath/bin/linux_amd64/test
* cccfac9dc10b2fe184581904bae8ae32a593f2d7369689ea8de92d42d82e4f8e  /tmp/gopath/bin/windows_386/test.exe
  0b9fd63afa1b5212a71912a5fa7b92d016fa53fdab7a6bd3368ff92cfeb87def  /tmp/gopath/bin/windows_amd64/test.exe

host=linux_386
* 4b356f6d7e5f8f236aa2340223bb4b6e96cd955f3615cd84d06f1fbeafc71bf2  /tmp/gopath/bin/darwin_386/test
  099d1ea0f08c12961871062175ed1eb0f08a9c3711a04ae7b065ed464d0f7c4e  /tmp/gopath/bin/darwin_amd64/test
* 9a0522c00d1b989650342efba689bd9d332fc3290d085a16949c626ce0822f02  /tmp/gopath/bin/linux_386/test
  0f56ffbe56fb47d76e34a174ca9a16e948ed31d0f1966d3ad3a9e4413bc21288  /tmp/gopath/bin/linux_amd64/test
* 35d36ded359656d9ae5dfa7f68a30585a0c327c622720bb34fbdf34dda912c0e  /tmp/gopath/bin/windows_386/test.exe
  0b9fd63afa1b5212a71912a5fa7b92d016fa53fdab7a6bd3368ff92cfeb87def  /tmp/gopath/bin/windows_amd64/test.exe

386 binaries for all 3 OS (Linux, Windows, Darwin) are different when building on Linux amd64 and Linux 386. However both hosts produce amd64 binaries that are exactly the same on any OS.

Darwin amd64 host produces the same binaries as Linux amd64.

@davecheney

This comment has been minimized.

Contributor

davecheney commented Oct 10, 2017

@ianlancetaylor ianlancetaylor changed the title from 386 and amd64 hosts produce different 386 binaries to cmd/link: 386 and amd64 hosts produce different 386 binaries Oct 10, 2017

@ianlancetaylor

This comment has been minimized.

Contributor

ianlancetaylor commented Oct 10, 2017

Yes, please try your tests setting CGO_ENABLED=1 (or CGO_ENABLED=0) in both cases.

@starius

This comment has been minimized.

starius commented Oct 11, 2017

I tried CGO_ENABLED=1 and CGO_ENABLED=0 but it didn't affect the resulting files.

@ianlancetaylor

This comment has been minimized.

Contributor

ianlancetaylor commented Oct 11, 2017

Can you show us the output of GOARCH=386 CGO_COMPILED=0 go build -x for your test case?

@ianlancetaylor

This comment has been minimized.

Contributor

ianlancetaylor commented Oct 11, 2017

Can you look into exactly how the different files are different? Perhaps by using the readelf or objdump programs?

@starius

This comment has been minimized.

starius commented Oct 11, 2017

Compiling from linux/amd64 -> linux/amd64 will produce a cgo enabled dynamically linked binary. All other operations will produce a statically linked static binary.

Disabling cgo didn't help. Also, changing host from linux_amd64 to linux_386 affected all 386 binaries (including darwin and windows), while changing host from linux_amd64 to darwin_amd64 didn't affect any binary. So it doesn't look like it is as simple as special treatment of cases when host=target.

@starius

This comment has been minimized.

starius commented Oct 11, 2017

Can you show us the output of GOARCH=386 CGO_COMPILED=0 go build -x for your test case?

https://gist.github.com/starius/495ff3943ac338b8472cce771d2d136b (go install instead of go build but should not be a big deal. Also for GOOS=linux only.)

@starius

This comment has been minimized.

starius commented Oct 11, 2017

Can you look into exactly how the different files are different? Perhaps by using the readelf or objdump programs?

diff of objdumps: https://pastebin.com/HATEiHdk

Original files (xxd of):
built on linux_386: http://rgho.st/922ZdvC25
built on linux_amd64: http://rgho.st/66cJ89MjQ

BTW gist doesn't eat these files for some reason. I upload them and in one second they are already 404. So I uploaded to more friendly sites.

@bradfitz

This comment has been minimized.

Member

bradfitz commented May 29, 2018

/cc @FiloSottile (for reproducibility issues)

@ianlancetaylor ianlancetaylor modified the milestones: Go1.11, Go1.12 Jun 23, 2018

@ianlancetaylor

This comment has been minimized.

Contributor

ianlancetaylor commented Dec 7, 2018

I tried to repeat this problem but I was unable to. Can you see whether this is still a problem for you today? Thanks.

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