Closed am11 closed 2 years ago
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.
Tagging subscribers to 'size-reduction': @eerhardt, @SamMonoRT, @marek-safar See info in area-owners.md if you want to be subscribed.
Author: | am11 |
---|---|
Assignees: | - |
Labels: | `untriaged`, `size-reduction`, `area-NativeAOT-coreclr` |
Milestone: | - |
For NativeAOT, we try to follow platform conventions whenever reasonable. AFAIK debug information embedded in the executable is the platform convention on Unix-like systems. Is that not the case?
FWIW, we document this on https://aka.ms/OptimizeNativeAOT (bottom of the doc).
Is that not the case?
I am not sure what is the particular Unix wide convention and if there is one, but most binaries I have found on my Ubuntu 20.04 box are stripped:
# number of stripped binaries in /usr/bin
$ find /usr/bin -exec file -L {} \; | grep stripped | grep -v "not stripped" | wc -l
1697
# number of non-stripped binaries in /usr/bin
$ find /usr/bin -exec file -L {} \; | grep "not stripped" | wc -l
6
Also, all .NET binaries are stripped on linux, including apphost / singlefilehost, so the apps published with corehost are also stripped.
I mean the default settings for the compiler that produces the executable. Maybe what we want is an easier way to opt in?
(I'm not Unix person myself, so don't have an opinion besides "follow the platform convention").
gcc/clang defaults usually favor Unix legacy. e.g. a.out
is the default binary name which is based on the convention from pre-ELF / pre-System-V 1970's era, default output type is executable, PIC/PIE are not default (but highly recommended) etc. We do produce PIC by default, with no opting in or out, and therefore don't follow the defaults of complier toolchain.
From dotnet publish
view point, it would also make sense to align PublishAot
's behavior with PublishSingleFile
, which produce stripped binary. One key difference would be that .dbg file is produced next to the binary in case of NativeAOT (singlefilehost's native symbols are normally fetched from the server when SOS is installed). This way opt-in won't be necessary.
Opt-out is also unnecessary for this IMHO. Non-stripped binaries are generally not distributed. Folks who really want embedded symbols can use tools like eu-unstrip
to reverse this effect.
Note: user is not missing anything, all symbols are there, but in a separate "fat symbol file" (symbol file is rarely needed in production environment).
So cargo build
produces unstripped executables for Rust. One has to add extra stuff to cargo.toml to have cargo do it for you (added recently - https://github.com/rust-lang/cargo/pull/8246 - one had to pass extra ldflags before that).
I would still prefer to align with rustc/clang/gcc. Rustc doesn't have 50 years of legacy and they still chose unstripped to be the default.
Are there any examples of toolchains that strip by default? PublishSingleFile doesn't count because it doesn't actually generate an executable (it glues managed assemblies at the end of a preexisting executable - the symbols would be meaningless for the glued part).
Makes sense. I think having it optional and wire it with an msbuild property like <StripSymbols>true/false
would be enough.
Are there any examples of toolchains that strip by default?
I tested with nexe
(node.js native), it also produces unstripped binary.
@am11 Are you be interested in contributing the build targets for this to make it easy to opt-in into symbol stripping?
Repro:
Extracting symbols (in a separate .dbg file) reduced the hello world binary size by 67%. We should consider doing this by default.