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/go: executables built with -trimpath are not reproducible with development Go toolchains unless -ldflags removes -buildid= #59525

Closed
bcmills opened this issue Apr 10, 2023 · 15 comments
Labels
GoCommand cmd/go NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. Unfortunate
Milestone

Comments

@bcmills
Copy link
Member

bcmills commented Apr 10, 2023

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

$ go version
go version devel go1.21-63a08e61bd Mon Apr 10 17:13:41 2023 +0000 linux/amd64

Does this issue reproduce with the latest release?

Yes.

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

go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/bryan/.cache/go-build"
GOENV="/home/bryan/.config/go/env"
GOEXE=".exe"
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/bryan/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="windows"
GOPATH="/home/bryan"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/bryan/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/bryan/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="devel go1.21-63a08e61bd Mon Apr 10 17:13:41 2023 +0000"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="gcc"
CXX="c++"
CGO_ENABLED="0"
GOMOD="/dev/null"
GOWORK=""
CGO_CFLAGS="-O2 -g"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-O2 -g"
CGO_FFLAGS="-O2 -g"
CGO_LDFLAGS="-O2 -g"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-m64 -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build840843456=/tmp/go-build -gno-record-gcc-switches"

What did you do?

GOOS=windows CGO_ENABLED=0 go install -trimpath cmd/test2json using a Windows build of the Go toolchain and a Linux build of the Go toolchain checked out at the same commit.

What did you expect to see?

Since the two Go toolchains are built from the same source code, and they are both targeting the same platform, and neither should be using an external compiler or linker, the resulting binaries should be identical.

What did you see instead?

The binaries are only identical if I also pass -ldflags=all=-buildid=.

Adding the -x flag to the go install command confirms that cmd/go is passing different -buildid flags in the two configurations.

@bcmills bcmills added NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. GoCommand cmd/go labels Apr 10, 2023
@bcmills bcmills added this to the Go1.21 milestone Apr 10, 2023
@bcmills bcmills changed the title cmd/go: executables build with -trimpath are not reproducible on Windows unless -ldflags removes -buildid= cmd/go: executables built with -trimpath are not reproducible on Windows unless -ldflags removes -buildid= Apr 10, 2023
@rsc
Copy link
Contributor

rsc commented Apr 11, 2023

The build IDs in unversioned copies of Go include a hash of the compiler binary to incorporate the semantics of the compiler somehow (the version string is assumed good enough in a versioned copy, although that's only true if you don't modify the files in your versioned checkout), so this is working as expected.

@jrick
Copy link
Contributor

jrick commented Apr 11, 2023

We saw this behavior with 1.20.3 as well, not running tip.

@jrick
Copy link
Contributor

jrick commented Apr 11, 2023

Er, would that version string include the host operating system too?

@bcmills
Copy link
Member Author

bcmills commented Apr 11, 2023

Shouldn't, no. But maybe on 1.20.3 the build-ID depends on the GOAMD setting (which is the thing already fixed for 1.21). Maybe try checking out the development tree at HEAD, give it a VERSION file like go1.21.999999 (to avoid polluting the build cache if you forget to clean it), and see if that's enough?

@bcmills bcmills changed the title cmd/go: executables built with -trimpath are not reproducible on Windows unless -ldflags removes -buildid= cmd/go: executables built with -trimpath are not reproducible with development Go toolchains unless -ldflags removes -buildid= Apr 11, 2023
@jrick
Copy link
Contributor

jrick commented Apr 11, 2023

Sure, let me find a working commit first :)

>$ (cd src && bash all.bash)
Building Go cmd/dist using /usr/lib64/go/1.20. (go1.20.3 linux/amd64)
Building Go toolchain1 using /usr/lib64/go/1.20.
# bootstrap/internal/platform
/home/jrick/src/go/src/internal/platform/zcgo.go:8: undefined: osArchSupportsCgo
/home/jrick/src/go/src/internal/platform/zcgo.go:12: undefined: osArchSupportsCgo
go tool dist: FAILED: /usr/lib64/go/1.20/bin/go install -tags=math_big_pure_go compiler_bootstrap purego bootstrap/cmd/...: exit status 1

@rsc
Copy link
Contributor

rsc commented Apr 11, 2023

For Go 1.20 you have the default GOARM discrepancy on Linux vs Windows, so I'm not sure how you'd have gotten far enough that -ldflags=-buildid= would help.

@bcmills
Copy link
Member Author

bcmills commented Apr 11, 2023

@jrick, you'll want to git clean away the files from my pending CL that you patched in to test earlier. 😅

@rsc
Copy link
Contributor

rsc commented Apr 11, 2023

FWIW, creating a VERSION file that says 'go1.999' and then doing

GOOS=windows CGO_ENABLED=0 go install -trimpath cmd/test2json

is known to produce the same binaries on Linux and Windows, because that's a subset of what we were testing in #58884, which no one was able to break. It's possible something has broken since then, but unlikely.

I believe that if you:

  1. Start with a recent devel commit (not Go 1.20)
  2. Create a VERSION file that says:
    go1.21repro99
    time 2023-04-11T00:00:00Z
  3. Build the tree with cd src; ./make.bash -distpack

You should get identical output on any machine you run this on. The output is a hash of the overall distribution archive, which includes test2json as well as all the other binaries.

@jrick
Copy link
Contributor

jrick commented Apr 11, 2023

Can I leave out the 2nd time line?

C:\Users\jrick\src\go\src>make.bat -distpack
Building Go cmd/dist using C:\Program Files\Go. (go1.20.3 windows/amd64)
Building Go toolchain1 using C:\Program Files\Go.
Building Go bootstrap cmd/go (go_bootstrap) using Go toolchain1.
C:\Users\jrick\src\go\src\runtime\internal\math\math.go:7:8: could not import internal/goarch (object is [go object windows amd64 go1.21repro99
] expected [go object windows amd64 go1.21repro99
time 2023-04-11T00:00:00Z GOAMD64=v1 X:regabiwrappers,regabiargs
])

go tool dist: FAILED: C:\Users\jrick\src\go\pkg\tool\windows_amd64\compile -std -pack -o C:\Users\jrick\AppData\Local\Temp\go-tool-dist-1502108241\runtime\internal\math\_go_.a -p runtime/internal/math -importcfg C:\Users\jrick\AppData\Local\Temp\go-tool-dist-1502108241\runtime\internal\math\importcfg C:\Users\jrick\src\go\src\runtime\internal\math\math.go: exit status 2
C:\Users\jrick\src\go\src\runtime\internal\sys\consts.go:8:2: could not import internal/goarch (object is [go object windows amd64 go1.21repro99
] expected [go object windows amd64 go1.21repro99
time 2023-04-11T00:00:00Z GOAMD64=v1 X:regabiwrappers,regabiargs
])

@rsc
Copy link
Contributor

rsc commented Apr 11, 2023

What git commit are you building? That failure would happen if you were building an old (circa Go 1.20) copy of the source tree instead of a recent copy of the master branch.

@jrick
Copy link
Contributor

jrick commented Apr 11, 2023

Master (267b50a)

@rsc
Copy link
Contributor

rsc commented Apr 11, 2023

Oops! I confused myself about what is and is not checked in. The -distpack flag and the support for the 'time' line were still pending. I just submitted the CL seconds ago. You need 1635205 or later. Sorry.

@jrick

This comment was marked as outdated.

@jrick
Copy link
Contributor

jrick commented Apr 11, 2023

Ignore that i hid that last comment. I saw different build hashes with geth still and marked it outdated. The build of test2json is properly reproducible now on tip with VERSION.

@rsc
Copy link
Contributor

rsc commented Apr 11, 2023

Great! Closing this issue, and we can work on geth in #59500.

@rsc rsc closed this as completed Apr 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
GoCommand cmd/go NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. Unfortunate
Projects
None yet
Development

No branches or pull requests

3 participants