Skip to content

Huge binary size regression at nightly-2025-01-03 #139950

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

Closed
mikialex opened this issue Apr 17, 2025 · 9 comments
Closed

Huge binary size regression at nightly-2025-01-03 #139950

mikialex opened this issue Apr 17, 2025 · 9 comments
Labels
C-discussion Category: Discussion or questions that doesn't represent real issues. O-apple Operating system: Apple (macOS, iOS, tvOS, visionOS, watchOS) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@mikialex
Copy link

mikialex commented Apr 17, 2025

I observed a huge binary size regression in my project when updating the rust version to nightly-2025-01-03.

My project repo is https://github.com/mikialex/rendiation, and the build command is using cargo build --bin viewer --release. The typical release build of the viewer binary is 16.6mb(in master), but for any rust version after(include) nightly-2025-01-03, the binary size regressed to 29mb, nearly doubled.

I also compare the lto=true codegen-unit=1 release config, the master version yields a 14.8mb binary, but the regressed version yields a 21.4mb binary.

To reproduce this issue, simply go to the project's root, modify the rust-toolchain.toml the channel "nightly-2025-01-04"(I don't known why it's 04 not 03). It's not a small project(95k loc), I will continue trying to find simpler ways to reproduce.

Version it worked on

before rustc 1.85.0-nightly (4363f9b 2025-01-02)

It most recently worked on:

Version with regression

before rustc 1.85.0-nightly (3f43b1a 2025-01-03)

rustc --version --verbose:

rustc 1.86.0-nightly (3f43b1a63 2025-01-03)
binary: rustc
commit-hash: 3f43b1a636738f41c48df073c5bcb97a97bf8459
commit-date: 2025-01-03
host: aarch64-apple-darwin
release: 1.86.0-nightly
LLVM version: 19.1.6
@mikialex mikialex added C-bug Category: This is a bug. regression-untriaged Untriaged performance or correctness regression. labels Apr 17, 2025
@rustbot rustbot added I-prioritize Issue: Indicates that prioritization has been requested for this issue. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Apr 17, 2025
@tgross35
Copy link
Contributor

From the list at https://github.com/rust-lang/rust/pulls?q=is%3Apr+merged%3A2025-01-01..2025-01-03+is%3Aclosed+-label%3Arollup+ it looks like #135034 is likely to have affected things, but that should have improved things rather than made them worse. Iirc there may have been some follow up there, is this still large on the latest nightly?

If you get the chance, cargo-bisect-rustc should bisect to a specific commit to confirm. You can pass --prompt to and manually pass/fail based on binary size (or script it).

@jieyouxu jieyouxu added E-needs-bisection Call for participation: This issue needs bisection: https://github.com/rust-lang/cargo-bisect-rustc T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. O-apple Operating system: Apple (macOS, iOS, tvOS, visionOS, watchOS) labels Apr 17, 2025
@mikialex
Copy link
Author

I tested on the latest nightly, it still produces large binary. I also did bisect using cargo bisect-rustc --by-commit --prompt --start=2025-01-02 --end=2025-01-04 -- build --release, it turns out the regression indeed related to #135034 3f43b1a636738f41c48df073c5bcb97a97bf8459

@tgross35
Copy link
Contributor

Does passing -Cdebuginfo=2 -Cstrip=x make a difference for x=none, debuginfo, or symbols?

Cc @Noratrieb from the PR

@mikialex
Copy link
Author

If I add strip = "symbols", the issue get fixed.

strip = "none" make binary size sightly larger, strip = "debuginfo" has no effect.

@lqd
Copy link
Member

lqd commented Apr 17, 2025

That seems like a fix rather than a regression. What was the situation prior to #131405?

@mikialex
Copy link
Author

That seems like a fix rather than a regression. What was the situation prior to #131405?

After #131405, you have to specify the strip = "symbols" to achieve the same release build binary size as before. I think the default config(without specifying any strip or debuginfo detail) should consistently produce reasonably small output. So it's a regression.

@lqd
Copy link
Member

lqd commented Apr 17, 2025

As strip="symbols" breaks backtraces and more, it cannot be a default that works for everyone, it has to be opt-in.

To summarize:

  1. in the past, you had no strip config. Therefore, there was no stripping for your release builds: you had no debuginfo of your own, but your binary contained the std debuginfo, and of course no symbols were stripped away.
  2. In Strip debuginfo when debuginfo is not requested cargo#13257 cargo/rustc made the release profile behavior match the requested debuginfo level: the std debuginfo should now be stripped from your binary. It's unclear whether on OSX only debuginfo or symbols were stripped, but the intent is clearly the former: any other behavior, including the bugs due to homebrew's strip breaking binaries, is not expected.
  3. bootstrap/codegen_ssa: ship llvm-strip and use it for -Cstrip #131405 changed the binary used to strip and had a bug in its parameters, stripping debuginfo now stripped symbols.
  4. Pass objcopy args for stripping on OSX #135034 fixed that bug and we're now back at step 2

I believe that's accurate? Only debuginfo is stripped by default, for profiles that request no debuginfo to be produced. strip="symbols" was never intended to become the default in any of the above PRs.

@mikialex
Copy link
Author

Sorry, I mixed up #131405 with #135034. However, it's hard for me to switch to the rust version before #131405.

So.. #135034 introduced a bug that makes the binary wrongly small, then #131405 fixed this, which caused "regression". I think we can close this issue.

Another optional question is, I know my project contains a lot of complex types, but half of the binary is debug symbols seems not reasonable. Is there any way(except boxing type) to limit the generated symbol length to avoid this situation?

@jieyouxu jieyouxu added C-discussion Category: Discussion or questions that doesn't represent real issues. and removed C-bug Category: This is a bug. I-prioritize Issue: Indicates that prioritization has been requested for this issue. regression-untriaged Untriaged performance or correctness regression. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. E-needs-bisection Call for participation: This issue needs bisection: https://github.com/rust-lang/cargo-bisect-rustc labels Apr 17, 2025
@Noratrieb
Copy link
Member

If you want the smallest binaries, you should strip symbols explicitly with strip = "symbols"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-discussion Category: Discussion or questions that doesn't represent real issues. O-apple Operating system: Apple (macOS, iOS, tvOS, visionOS, watchOS) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

6 participants