-
-
Notifications
You must be signed in to change notification settings - Fork 15.4k
rustc: Fix corrupted .rlib files caused by stripping on Darwin #34227
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
Conversation
@@ -37,6 +37,9 @@ stdenv.mkDerivation { | |||
# The build will fail at the very end on AArch64 without this. | |||
dontUpdateAutotoolsGnuConfigScripts = if stdenv.isAarch64 then true else null; | |||
|
|||
# Running the default `strip -S` command corrupts the .rlib files. | |||
dontStrip = if stdenv.isDarwin then true else null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about stripDebugList = stdenv.lib.optional stdenv.isDarwin "bin";
instead of disabling it entirely.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's probably still desirable to strip the regular libraries in lib
, as well as bin
. We could copy the logic from strip.sh and modify it to skip .rlib
files on all platforms:
{
stripDebugList = [ "bin" ];
preInstall = ''
find lib -type f ! -name '*.rlib' -print0 | xargs -0 ${xargsFlags:--r} $stripCmd $commonStripFlags ${stripDebugFlags:--S} 2>/dev/null || true
'';
}
Or even modify strip.sh to have an extra filter argument?
Happy to go with any recommendation here. Just so long as .rlib
files are excluded.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, there's currently no nice way to exclude things. Adding something like stripExcludes
to the stdenv seems like the nicest solution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The change you suggested (restricting to only "bin" on Darwin) seems like the simplest way to fix this problem. Should we merge that to fix rust now, and then later see about adding exclusion to stdenv?
OMG ❤️ ❤️ ❤️ ❤️ ❤️ ❤️ thanks for tracking this down! |
Motivation for this change
And I believe this is also affecting
Things done
build-use-sandbox
innix.conf
on non-NixOS)nix-shell -p nox --run "nox-review wip"
./result/bin/
)When running
strip -S
on the .rlib files produced as part of the rust build, the archive will become corrupted. In particular, the last entry will declare its size 2 bytes bigger than it actually is. When attempting to scan for the next header atlastHeader + size
, the next header is located 2 bytes after the end of the archive, and hence the error messageAt a glance, the archive still looks coherent.
I wrote some throwaway code to introspect the archive, and learned a bit about what strip does to the archive structure. When
strip
processes the archive it rewrites all of the headers introducing additional padding to the names and sorts the symbol table.Using
llvm-ar
as a test, one can quickly verify thatstrip -S
causes the breakage:I don't know if it's valid to rewrite the contents of an
.rlib
file as if it were a regular archive using standard tools on any platform, since I'm assuming they're rust internal implementation detail. However I only disabled it on Darwin since that's where the problem is. Also I didn't see a way to exclude only.rlib
files from the default stripping, which would be a more precise fix.While we're here, when strip sorts the symbol table, it also includes some build-specific information that will make the build not bit-for-bit reproducible:
First header, not stripped:
First header, stripped (from nixpkgs binary cache):