google / bloaty

Bloaty: a size profiler for binaries
Apache License 2.0
4.73k stars 342 forks source link

Rust symbol demangling #110

Open zokier opened 6 years ago

zokier commented 6 years ago

This came up in HN discussion that Bloaty does not have currently demangling for Rust symbols, and such feature would be useful.

There are at least two different libraries that implement Rust demangling:

1) GNU libiberty: https://github.com/gcc-mirror/gcc/blob/master/libiberty/rust-demangle.c

2) rustc-demangle: https://github.com/alexcrichton/rustc-demangle

The latter has the downside of being implemented in Rust, so a small wrapper is needed to make it work with C++ code. Might need bit of work to make it play with CMake nicely.

I have made a quick proof of concept version based on rustc-demangle here: https://github.com/zokier/bloaty/tree/rust_demangle

zokier commented 6 years ago

Shifting the discussion to this issue..

I think I'd prefer to just make this part of shortsymbols/fullsymbols instead of making a separate "rustsymbols". I assume that Rust symbols won't successfully demangle as C++ (and vice-versa), so we can just try both demanglers and use whatever works. That seems like it will be more graceful for mixed C++/Rust binaries.

That would be indeed nicer, but I'm not sure if it is easily achievable, because Rust and C++ manglings are so similar. I'm not expert on this, so do not take my word on this, but testing shortsymbols/fullsymbols on a Rust executable results partial demangling:

[zokier@zarch bloaty]$ ./bloaty -d shortsymbols /tmp/tinyrocket/target/release/tinyrocket
     VM SIZE                                                                                        FILE SIZE
 --------------                                                                                  --------------
  65.7%   640Ki [2303 Others]                                                                      875Ki  42.8%
   0.0%       0 [section .debug_str]                                                               259Ki  12.7%
   0.0%       0 [section .debug_info]                                                              227Ki  11.2%
   0.0%       0 [section .debug_ranges]                                                            107Ki   5.3%
   0.0%       0 [section .debug_pubnames]                                                         94.6Ki   4.6%
   9.2%  89.5Ki idna::uts46::find_char::hf4b73b1817809953                                         89.5Ki   4.4%
   0.0%       0 [section .debug_line]                                                             81.1Ki   4.0%
   7.2%  69.9Ki unicode_normalization::normalize::d::h2e71db9e521747a3                            70.0Ki   3.4%
   0.0%       0 [section .debug_pubtypes]                                                         48.4Ki   2.4%
   3.3%  32.1Ki rocket::config::RocketConfig::override_from_env::h2f1179166e400e61                32.2Ki   1.6%
   3.3%  31.9Ki hyper::server::listener::spawn_with::_$u7b$$u7b$closure$u7d$$u7d$::h3691293af625  32.0Ki   1.6%
   1.7%  16.6Ki rocket::ignite::hee6613aa2a5fcf8a                                                 16.6Ki   0.8%
   1.7%  16.2Ki rocket::config::config::Config::set_raw::hb13b072d56297a7e                        16.3Ki   0.8%
   1.6%  15.4Ki unicode_bidi::char_data::bidi_class::he12c0681b23bfdb2                            15.5Ki   0.8%
   0.0%       0 [section .debug_macro]                                                            13.2Ki   0.6%
   1.3%  13.2Ki tinyrocket::main::h8716512f8746ab53                                               13.2Ki   0.6%
   1.3%  12.4Ki idna::uts46::decode_slice::hd86b0f78245a9e42                                      12.5Ki   0.6%
   1.2%  12.1Ki std::sys_common::backtrace::output::hc58f0399059446b5                             12.2Ki   0.6%
   1.1%  10.7Ki unicode_normalization::normalize::compose::h51bcd650cea02388                      10.8Ki   0.5%
   0.8%  7.83Ki rocket::request::request::Request::format::h73a5bf51e7bffce6                      7.92Ki   0.4%
   0.7%  6.45Ki rocket::rocket::Rocket::dispatch::hf52688098d427981                               6.53Ki   0.3%
 100.0%   974Ki TOTAL                                                                             2.00Mi 100.0%

[zokier@zarch bloaty]$ ./bloaty -d fullsymbols /tmp/tinyrocket/target/release/tinyrocket
     VM SIZE                                                                                        FILE SIZE
 --------------                                                                                  --------------
  65.7%   640Ki [2316 Others]                                                                      875Ki  42.8%
   0.0%       0 [section .debug_str]                                                               259Ki  12.7%
   0.0%       0 [section .debug_info]                                                              227Ki  11.2%
   0.0%       0 [section .debug_ranges]                                                            107Ki   5.3%
   0.0%       0 [section .debug_pubnames]                                                         94.6Ki   4.6%
   9.2%  89.5Ki idna::uts46::find_char::hf4b73b1817809953                                         89.5Ki   4.4%
   0.0%       0 [section .debug_line]                                                             81.1Ki   4.0%
   7.2%  69.9Ki unicode_normalization::normalize::d::h2e71db9e521747a3                            70.0Ki   3.4%
   0.0%       0 [section .debug_pubtypes]                                                         48.4Ki   2.4%
   3.3%  32.1Ki rocket::config::RocketConfig::override_from_env::h2f1179166e400e61                32.2Ki   1.6%
   3.3%  31.9Ki hyper::server::listener::spawn_with::_$u7b$$u7b$closure$u7d$$u7d$::h3691293af625  32.0Ki   1.6%
   1.7%  16.6Ki rocket::ignite::hee6613aa2a5fcf8a                                                 16.6Ki   0.8%
   1.7%  16.2Ki rocket::config::config::Config::set_raw::hb13b072d56297a7e                        16.3Ki   0.8%
   1.6%  15.4Ki unicode_bidi::char_data::bidi_class::he12c0681b23bfdb2                            15.5Ki   0.8%
   0.0%       0 [section .debug_macro]                                                            13.2Ki   0.6%
   1.3%  13.2Ki tinyrocket::main::h8716512f8746ab53                                               13.2Ki   0.6%
   1.3%  12.4Ki idna::uts46::decode_slice::hd86b0f78245a9e42                                      12.5Ki   0.6%
   1.2%  12.1Ki std::sys_common::backtrace::output::hc58f0399059446b5                             12.2Ki   0.6%
   1.1%  10.7Ki unicode_normalization::normalize::compose::h51bcd650cea02388                      10.8Ki   0.5%
   0.8%  7.83Ki rocket::request::request::Request::format::h73a5bf51e7bffce6                      7.92Ki   0.4%
   0.7%  6.45Ki rocket::rocket::Rocket::dispatch::hf52688098d427981                               6.53Ki   0.3%
 100.0%   974Ki TOTAL                                                                             2.00Mi 100.0%

[zokier@zarch bloaty]$ ./bloaty -d rustsymbols /tmp/tinyrocket/target/release/tinyrocket
     VM SIZE                                                        FILE SIZE
 --------------                                                  --------------
  63.2%   616Ki [1279 Others]                                      812Ki  39.8%
   0.0%       0 [section .debug_str]                               259Ki  12.7%
   0.0%       0 [section .debug_info]                              227Ki  11.2%
   0.0%       0 [section .debug_ranges]                            107Ki   5.3%
   0.0%       0 [section .debug_pubnames]                         94.6Ki   4.6%
   9.2%  89.5Ki idna::uts46::find_char                            89.5Ki   4.4%
   0.0%       0 [section .debug_line]                             81.1Ki   4.0%
   7.2%  69.9Ki unicode_normalization::normalize::d               70.0Ki   3.4%
   0.0%       0 [section .debug_pubtypes]                         48.4Ki   2.4%
   2.2%  21.3Ki core::ptr::drop_in_place                          43.8Ki   2.1%
   3.3%  32.1Ki rocket::config::RocketConfig::override_from_env   32.2Ki   1.6%
   3.3%  31.9Ki hyper::server::listener::spawn_with::{{closure}}  32.0Ki   1.6%
   2.0%  19.6Ki <yansi::Paint<T> as core::fmt::Display>::fmt      21.6Ki   1.1%
   1.4%  13.2Ki <&'a T as core::fmt::Display>::fmt                18.2Ki   0.9%
   1.7%  16.6Ki rocket::ignite                                    16.6Ki   0.8%
   1.7%  16.2Ki rocket::config::config::Config::set_raw           16.3Ki   0.8%
   1.6%  15.4Ki unicode_bidi::char_data::bidi_class               15.5Ki   0.8%
   0.9%  8.76Ki <&'a T as core::fmt::Debug>::fmt                  14.5Ki   0.7%
   1.1%  10.7Ki <alloc::raw_vec::RawVec<T, A>>::double            14.2Ki   0.7%
   0.0%       0 [section .debug_macro]                            13.2Ki   0.6%
   1.3%  13.2Ki tinyrocket::main                                  13.2Ki   0.6%
 100.0%   974Ki TOTAL                                             2.00Mi 100.0%
[zokier@zarch bloaty]$ 
luser commented 2 years ago

An annoying user-visible piece of this is that Rust symbols have a hash suffix on them (to allow linking multiple major versions of the same crate into the same binary, if desired), you can see the ::hNNNNN suffixes in the output above. This means that trying to use bloaty to do a symbol-wise diff between two versions of a binary that includes Rust code doesn't work, because the same symbols in the binaries can wind up with different hashes. :-|

n.b. the current in-use Rust mangling scheme is backwards-compatible with Itanium C++ name mangling for compatibility reasons. However, there's a Rust Symbol Mangling (v0) RFC which has not yet stabilized that specifies a Rust-specific mangling that is unambiguous.

kupiakos commented 1 year ago

Are there any further updates on this?