Removing backtrace & demangling support from Rust executables

I would like to rip out as much functionality related to panics and backtraces as possible from release executables that use libstd. No addr2line, no rustc_demangle, and preferably no support for any panic machinery besides immediately crashing the program with as few instructions as possible. Compiling with panic=abort is insufficient for this, since it still compiles in all the code required to collect and print the panic and its backtrace.

Is there a nightly feature for it? Is there any RFC planning to expose a setting like panic=abort-harder?

Is it possible to compile out backtrace support by using xargo? I've found some mentions of panic_immediate_abort std feature, but if I simply set it in Xargo.toml, I get errors that suggest this feature is for no_std programs only (I'd like to use std). I'm not sure if I'm configuring it wrong, or is it defunct or for no_std only.

Oh, it's easier than I thought!

cargo +nightly build --release -Z build-std=std,panic_abort -Z build-std-features=panic_immediate_abort --target $target
5 Likes

If you don't mind, how much are you able to save?

With strip and lto = "fat" macOS "hello world" dropped from 283824 to 68712 bytes.

Before

 6.5%  11.8%  25.3KiB       std addr2line::ResDwarf<R>::parse
 3.0%   5.5%  11.8KiB       std addr2line::Context<R>::find_frames
 2.8%   5.1%  11.0KiB       std std::backtrace_rs::symbolize::gimli::resolve
 2.6%   4.6%   9.9KiB       std addr2line::ResUnit<R>::parse_lines
 2.4%   4.3%   9.2KiB [Unknown] __mh_execute_header
 1.5%   2.8%   6.0KiB       std std::backtrace_rs::symbolize::gimli::macho::Object::parse
 1.2%   2.3%   4.8KiB       std gimli::read::unit::parse_attribute
 1.2%   2.2%   4.8KiB       std core::slice::sort::recurse
 1.2%   2.2%   4.7KiB       std core::slice::sort::recurse
 1.2%   2.1%   4.6KiB       std rustc_demangle::v0::Printer::print_type
 1.1%   2.1%   4.5KiB       std rustc_demangle::v0::Printer::print_const
 1.0%   1.8%   3.9KiB       std core::slice::sort::recurse
 0.9%   1.7%   3.6KiB       std std::backtrace_rs::symbolize::gimli::Context::new
 0.9%   1.7%   3.6KiB       std object::read::archive::ArchiveMember::parse
 0.9%   1.6%   3.5KiB       std addr2line::function::Function<R>::parse_children
 0.9%   1.6%   3.5KiB       std rustc_demangle::v0::Printer::print_path
 0.8%   1.5%   3.2KiB       std <&T as core::fmt::Display>::fmt
 0.8%   1.5%   3.2KiB       std gimli::read::unit::Attribute<R>::value
 0.8%   1.4%   3.0KiB       std rustc_demangle::try_demangle
 0.7%   1.3%   2.8KiB [Unknown] _main

After

10.0%  35.6%  7.7KiB    [Unknown] __mh_execute_header
 2.5%   9.1%  2.0KiB    [Unknown] _main
 2.3%   8.2%  1.8KiB          std core::panicking::assert_failed
 1.3%   4.8%  1.0KiB         core core::fmt::Formatter::pad_integral

It's not perfect — there's more panic machinery left than I'd like, but I'm happy that build-std is a thing now, and it worked on the first try. It doesn't even take long to compile.

3 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.