-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
regression in deterministic codegen from 1.32 to 1.33 when using --remap-path-prefix to compensate for change in source dir #59542
Comments
AFAIK we have very few tests for reproducible builds, so this probably slipped in by accident. cc @rust-lang/compiler - do we care enough about reproducible builds to consider this a stable-to-stable regression at this point? I know that quite a lot of people want reproducibility in their builds. |
This looks like a linker thing? Did we do anything wrt using lld or something like that? |
@jhfrontz Can you post a diff of symbol names and sizes? The assembly will ofc differ a lot, but I expect everything to be the same size, just shuffled around. |
@eddyb asks:
Are you wanting the output of I'll include the last ( |
@eddyb I got approval to include the full . |
This is most frequently an accidental regression in LLVM, although we've had bugs slip in with rustc as well! No major change to linker behavior in 1.32 -> 1.33. @jhfrontz the best way to get this fixed is if a test case can be reduced to isolate the issue. Would it be possible to minimize this to extract a small piece of code which exhibits the reproducibility issue? |
@alexcrichton asks:
I haven't been able to -- my simple "hello, world" toy programs always result in the same binary. It's only when I build production (proprietary) code that I'm seeing this. Full disclosure: I barely know enough rust to be able to run |
Sorry, I didn't see the notification. |
I just did this: gunzip ~/Downloads/objdump-t-{1,2}.txt.gz
cat ~/Downloads/objdump-t-1.txt | grep _ZN | sed -E 's/^.* +([^ ]+)$/\1/' | sort > sym1
cat ~/Downloads/objdump-t-2.txt | grep _ZN | sed -E 's/^.* +([^ ]+)$/\1/' | sort > sym2 And... the hashes don't match. These are using the same rustc binary, right? Can you run |
I'm using the same binary (everything is the same, including the time -- via libfaketime).
I'm building with However, the ordering of the crates listed in the metadata from two builds is different. Also, the Attached are the dumps from 3-libuuid-nm.txt Just to recall -- this still works as expected (producing deterministic binary) if I revert to rustc version 1.32. I ran it twice with 1.32 and
|
Ah, yeah, Also, by
Not sure what you mean by "metadata" here (I was referring to a hash Cargo passes to each rustc invocation). |
Nominating for discussion at the next @rust-lang/compiler meeting, as this seems more and more like it's a regression in how we handle source paths. |
The ordering of
|
@michaelwoerister I was referring to the contents, not ordering. But from what you're saying, Or did we start hashing the |
I'd like to have an actual reproducer for this. Otherwise it's hard to dig any deeper. |
We discussed in T-compiler team meeting today. removing nominated tag. |
(and I'm going to hijack the "S-waiting-on-author" tag to mean "waiting on more info from issue filer.") |
I found a smallish open-source project that demonstrates the issue. Run |
@michaelwoerister Oh, if |
@eddyb wrote
I just realized that you may have been asking me to do some further data gathering -- if so, I'm not sure I understand what you're requesting. Should I unroll the loop in build.sh.txt and have the |
I don't think incremental compilation should be used at all when trying to create reproducible builds. @jhfrontz, could you try to set |
@michaelwoerister suggests:
No effect; problem in 1.33 persists:
For comparison, 1.32:
|
I just checked the relevant source, and, yeah, I don't know why this would work. |
It fails for me without the remapping. And checking the outputted binary it has a lot of stuff like
i.e. the full path is there, not the literal |
Also -- |
I believe this would explain why at least some cases are handled: rust/src/librustc_metadata/encoder.rs Lines 346 to 356 in 9b67bd4
@jhfrontz I'm not sure I can figure that out without a binary diff between the two binaries. I doubt The problem is I don't know what kind of paths you have, and the first component in each path matters. But maybe the right approach would be rust-lang/cargo#6503 being changed to not affect |
Unfortunately the purpose of that Cargo PR is to affect |
It would be nice if there were a flag. I wouldn't want to back out the PR. I'm surprised we didn't see more problems before the Cargo PR; I seem to recall a lot of trouble a year or so ago with Miri caused by not enough things going into Having said that, based on @jhfrontz's original post, and our inability to use the |
@alexcrichton Ah, I misunderstood an important aspect: all the artifacts are kept in the same directory, and only |
@eddyb that plus it's the granularity Cargo caches at. The intention of the PR was that if you oscillate back and forth on |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Hey, to re-iterate: There is no way to have reproducible builds via Cargo from different source directories if Cargo feeds the RUSTFLAGS value into the |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
OK, it turns out that it is cargo that is causing the issue (@eddyb found that I wasn't actually using the 1.32 version of cargo in my earlier experiments). Now, with cargo-1.32 and rust-1.34, I get deterministic output:
|
I've just hidden a bunch of comments that were really confusing because of unrigorous debugging. Also, as we've determined this was entirely caused by Cargo, I've opened rust-lang/cargo#6914 instead, and I'm closing this issue on the Rust side. |
I use a gitian build environment to compile rust source in a well-defined/stabile environment. When using rust 1.32 (rust-1.32.0-1.el7.x86_64.rpm on Centos 7), I can deterministically build object/binary (with the help of
RUSTFLAGS="--remap-path-prefix=%{_builddir}=BUILDDIR -C link-arg=-Wl,--build-id=0x%{githash},-S"
while running inside anrpmbuild
) -- like, the build process when using 1.32 is so deterministic between runs that I can usediff
(orcmp
orsha256sum
) to verify that two products/executables produced on different runs are identical.However, as of 1.33 (rust-1.33.0-2.el7.x86_64.rpm on Centos 7), I get significant variation from one run to another:
Among other things, the layout of the address space seems to vary (sample):
Was something intentionally changed in 1.33 that might cause this behavior?
EDIT incorporating subsequent info:
I found a smallish open-source project that demonstrates the issue. Run
build.sh.txt -- under 1.32, I get all good; under 1.33, I get bad stuff.
The text was updated successfully, but these errors were encountered: