golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
121.24k stars 17.37k forks source link

cmd/go,cmd/link: TestScript/build_issue48319 and TestScript/build_plugin_reproducible failing on LUCI gotip-darwin-amd64-longtest builder due to non-reproducible LC_UUID #64947

Closed prattmic closed 1 month ago

prattmic commented 6 months ago

(It is unclear to me if this is an issue with the test, cmd/go, the compiler/linker, or the builder itself)

Example failure: https://ci.chromium.org/ui/inv/build-8759926960216361809/test-results?sortby=&groupby=

Both tests are failing because they aren't getting a reproducible build.

    script_test.go:156: FAIL: testdata/script/build_issue48319.txt:29: cmp -q main.exe main1.exe: main.exe and main1.exe differ
    script_test.go:156: FAIL: testdata/script/build_plugin_reproducible.txt:6: cmp -q a.so b.so: a.so and b.so differ

I haven't yet been able to reproduce on a gomote because the LUCI gomote setup doesn't currently set up Xcode properly, so cgo doesn't work (which these tests require).

cc @bcmills @dmitshur @mknyszek @cagedmantis

thanm commented 1 month ago

OK, latest go-round: following CL 585355 if I run this sequence of commands (essentially the guts of the plugin repro test) on the gotip-darwin-amd64-longtest gomote (with Xcode 15E204a):

rm -f a.so b.so

# First build
rm -rf /tmp/tmp
mkdir /tmp/tmp
go build -trimpath -buildvcs=false -buildmode=plugin -o a.so \
      -ldflags=-tmpdir=/tmp/tmp main.go 1> err1.txt 2>&1

# Second build
rm -rf /tmp/tmp
mkdir /tmp/tmp
go build -trimpath -buildvcs=false -buildmode=plugin -o b.so \
   -ldflags=-tmpdir=/tmp/tmp main.go 1> err2.txt 2>&1

# Compare
cmp a.so b.so

I can execute this 50, 100, 200 times and it works every time. If I remove the -ldflags=-tmpdir=/tmp/tmp flag from the build, then the compare works most of the time but fails maybe once every 10 or 20 iterations.

So: working theory: external linker seems to sometimes (not always, who knows why) take into account the path to the object files being fed it when it generates the UUID.

At this point I am now leaning towards falling back on Cherry's second suggestions: run the external linker and then just stomp on the uuid in the generated binary.

gopherbot commented 1 month ago

Change https://go.dev/cl/586079 mentions this issue: cmd/link/internal/ld: rewrite LC_UUID for darwin external links