Skip to content
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

Rust symbol demangling #655

Open
honggyukim opened this issue Jan 20, 2019 · 13 comments
Open

Rust symbol demangling #655

honggyukim opened this issue Jan 20, 2019 · 13 comments

Comments

@honggyukim
Copy link
Collaborator

I've found some symbols from Rust that are not human friendly. Please see.

$ cat rust-symbols.txt
_ZN12rustc_driver6driver34phase_2_configure_and_expand_inner28_$u7b$$u7b$closure$u7d$$u7d$17h19b3069eedb2aa0eE.llvm.10317035631373510462
_ZN13rustc_resolve6macros95_$LT$impl$u20$syntax..ext..base..Resolver$u20$for$u20$rustc_resolve..Resolver$LT$$u27$a$GT$$GT$36visit_ast_fragment_with_placeholders17hf0888d70da343677E
_ZN145_$LT$rustc_resolve..build_reduced_graph..BuildReducedGraphVisitor$LT$$u27$a$C$$u20$$u27$b$GT$$u20$as$u20$syntax..visit..Visitor$LT$$u27$a$GT$$GT$10visit_item17hb150e47151208e8cE
_ZN85_$LT$alloc..vec..Vec$LT$T$GT$$u20$as$u20$alloc..vec..SpecExtend$LT$T$C$$u20$I$GT$$GT$9from_iter17h2062241170cc9962E
_ZN13rustc_resolve19build_reduced_graph55_$LT$impl$u20$rustc_resolve..Resolver$LT$$u27$a$GT$$GT$28populate_module_if_necessary17hbb441b810ef2f737E
_ZN13rustc_resolve6macros95_$LT$impl$u20$syntax..ext..base..Resolver$u20$for$u20$rustc_resolve..Resolver$LT$$u27$a$GT$$GT$15resolve_imports17h3828c95b196b1a3eE
_ZN12rustc_driver6driver27phase_3_run_analysis_passes17hdb2010f2e99be787E
_ZN4core3ptr18real_drop_in_place17h11c589efaa8cb821E
_ZN111_$LT$rustc_codegen_llvm..LlvmCodegenBackend$u20$as$u20$rustc_codegen_utils..codegen_backend..CodegenBackend$GT$21join_codegen_and_link17hd599938021451cc5E
_ZN50_$LT$F$u20$as$u20$alloc..boxed..FnBox$LT$A$GT$$GT$8call_box17h4c8a656ad87c3337E
_ZN13rustc_resolve19build_reduced_graph55_$LT$impl$u20$rustc_resolve..Resolver$LT$$u27$a$GT$$GT$28populate_module_if_necessary17hbb441b810ef2f737E
_ZN14rustc_metadata11cstore_impl48_$LT$impl$u20$rustc_metadata..cstore..CStore$GT$23item_children_untracked17h022dcfab3027e755E
_ZN14rustc_metadata7decoder55_$LT$impl$u20$rustc_metadata..cstore..CrateMetadata$GT$18each_child_of_item17h46b74a1d0f9a5866E
_ZN168_$LT$rustc_metadata..decoder..DecodeContext$LT$$u27$a$C$$u20$$u27$tcx$GT$$u20$as$u20$serialize..serialize..SpecializedDecoder$LT$syntax_pos..span_encoding..Span$GT$$GT$18specialized_decode17h4a6bd5763c741c0aE
_ZN14rustc_metadata7decoder55_$LT$impl$u20$rustc_metadata..cstore..CrateMetadata$GT$21imported_source_files17h8b761ab49aa0fdabE
_ZN85_$LT$alloc..vec..Vec$LT$T$GT$$u20$as$u20$alloc..vec..SpecExtend$LT$T$C$$u20$I$GT$$GT$9from_iter17h62479432b9e0e63dE
_ZN84_$LT$core..iter..Map$LT$I$C$$u20$F$GT$$u20$as$u20$core..iter..iterator..Iterator$GT$4fold17h6bd1613295c5cc3bE
_ZN13rustc_resolve6macros95_$LT$impl$u20$syntax..ext..base..Resolver$u20$for$u20$rustc_resolve..Resolver$LT$$u27$a$GT$$GT$15resolve_imports17h3828c95b196b1a3eE
_ZN13rustc_resolve15resolve_imports14ImportResolver15resolve_imports17h1d147c237e1b06c0E
_ZN13rustc_resolve19build_reduced_graph55_$LT$impl$u20$rustc_resolve..Resolver$LT$$u27$a$GT$$GT$28populate_module_if_necessary17hbb441b810ef2f737E
_ZN14rustc_metadata11cstore_impl48_$LT$impl$u20$rustc_metadata..cstore..CStore$GT$23item_children_untracked17h022dcfab3027e755E
_ZN14rustc_metadata7decoder55_$LT$impl$u20$rustc_metadata..cstore..CrateMetadata$GT$18each_child_of_item17h46b74a1d0f9a5866E
_ZN168_$LT$rustc_metadata..decoder..DecodeContext$LT$$u27$a$C$$u20$$u27$tcx$GT$$u20$as$u20$serialize..serialize..SpecializedDecoder$LT$syntax_pos..span_encoding..Span$GT$$GT$18specialized_decode17h4a6bd5763c741c0aE
_ZN14rustc_metadata7decoder55_$LT$impl$u20$rustc_metadata..cstore..CrateMetadata$GT$21imported_source_files17h8b761ab49aa0fdabE
_ZN85_$LT$alloc..vec..Vec$LT$T$GT$$u20$as$u20$alloc..vec..SpecExtend$LT$T$C$$u20$I$GT$$GT$9from_iter17h62479432b9e0e63dE
_ZN84_$LT$core..iter..Map$LT$I$C$$u20$F$GT$$u20$as$u20$core..iter..iterator..Iterator$GT$4fold17h6bd1613295c5cc3bE
_ZN46_$LT$std..thread..local..LocalKey$LT$T$GT$$GT$4with17hfa2112d7831da9bdE
_ZN12rustc_typeck11check_crate17hff96fb41fa5237f9E
_ZN5rustc4util6common4time17h53daeca5cf904c3eE
_ZN5rustc2ty5query8plumbing90_$LT$impl$u20$rustc..ty..context..TyCtxt$LT$$u27$a$C$$u20$$u27$gcx$C$$u20$$u27$tcx$GT$$GT$12try_get_with17he823459c511e55c5E
_ZN5rustc9dep_graph5graph8DepGraph14with_task_impl17ha513f9ddad293b48E.llvm.11170816418846394767
_ZN5rustc2ty5query148_$LT$impl$u20$rustc..ty..query..config..QueryAccessors$LT$$u27$tcx$GT$$u20$for$u20$rustc..ty..query..queries..typeck_item_bodies$LT$$u27$tcx$GT$$GT$7compute17h8927c0bd3e117e34E
_ZN5rustc2ty5query15__query_compute18typeck_item_bodies17h4a12575681458c30E
_ZN12rustc_typeck5check18typeck_item_bodies17hfaa6e0ab992179a2E.llvm.1176616955897659555
_ZN5rustc7session7Session12track_errors17h8b4edd454bed47f1E
_ZN5rustc2ty5query77_$LT$impl$u20$rustc..ty..query..queries..typeck_tables_of$LT$$u27$tcx$GT$$GT$6ensure17h373b726fedcc99c7E
_ZN5rustc2ty5query8plumbing90_$LT$impl$u20$rustc..ty..context..TyCtxt$LT$$u27$a$C$$u20$$u27$gcx$C$$u20$$u27$tcx$GT$$GT$12ensure_query17h73e08f33e6d1aa10E
_ZN5rustc2ty5query8plumbing90_$LT$impl$u20$rustc..ty..context..TyCtxt$LT$$u27$a$C$$u20$$u27$gcx$C$$u20$$u27$tcx$GT$$GT$12try_get_with17hb0ee0e148c611728E
_ZN5rustc9dep_graph5graph8DepGraph14with_task_impl17ha97b247d2a229a88E.llvm.14625429544829335148
_ZN5rustc2ty5query146_$LT$impl$u20$rustc..ty..query..config..QueryAccessors$LT$$u27$tcx$GT$$u20$for$u20$rustc..ty..query..queries..typeck_tables_of$LT$$u27$tcx$GT$$GT$7compute17h743c69d46831c5a5E

The demangling output looks as follows:

$ cat rust-symbols.txt | xargs ./misc/demangler
rustc_driver::driver::phase_2_configure_and_expand_inner::_{{closure}}
rustc_resolve::macros::_<impl syntax..ext..base..Resolver for rustc_resolve..Resolver<'a>>::visit_ast_fragment_with_placeholders
_<rustc_resolve..build_reduced_graph..BuildReducedGraphVisitor<'a, 'b> as syntax..visit..Visitor<'a>>::visit_item
_<alloc..vec..Vec<T> as alloc..vec..SpecExtend<T, I>>::from_iter
rustc_resolve::build_reduced_graph::_<impl rustc_resolve..Resolver<'a>>::populate_module_if_necessary
rustc_resolve::macros::_<impl syntax..ext..base..Resolver for rustc_resolve..Resolver<'a>>::resolve_imports
rustc_driver::driver::phase_3_run_analysis_passes
core::ptr::real_drop_in_place
_<rustc_codegen_llvm..LlvmCodegenBackend as rustc_codegen_utils..codegen_backend..CodegenBackend>::join_codegen_and_link
_<F as alloc..boxed..FnBox<A>>::call_box
rustc_resolve::build_reduced_graph::_<impl rustc_resolve..Resolver<'a>>::populate_module_if_necessary
rustc_metadata::cstore_impl::_<impl rustc_metadata..cstore..CStore>::item_children_untracked
rustc_metadata::decoder::_<impl rustc_metadata..cstore..CrateMetadata>::each_child_of_item
_<rustc_metadata..decoder..DecodeContext<'a, 'tcx> as serialize..serialize..SpecializedDecoder<syntax_pos..span_encoding..Span>>::specialized_decode
rustc_metadata::decoder::_<impl rustc_metadata..cstore..CrateMetadata>::imported_source_files
_<alloc..vec..Vec<T> as alloc..vec..SpecExtend<T, I>>::from_iter
_<core..iter..Map<I, F> as core..iter..iterator..Iterator>::fold
rustc_resolve::macros::_<impl syntax..ext..base..Resolver for rustc_resolve..Resolver<'a>>::resolve_imports
rustc_resolve::resolve_imports::ImportResolver::resolve_imports
rustc_resolve::build_reduced_graph::_<impl rustc_resolve..Resolver<'a>>::populate_module_if_necessary
rustc_metadata::cstore_impl::_<impl rustc_metadata..cstore..CStore>::item_children_untracked
rustc_metadata::decoder::_<impl rustc_metadata..cstore..CrateMetadata>::each_child_of_item
_<rustc_metadata..decoder..DecodeContext<'a, 'tcx> as serialize..serialize..SpecializedDecoder<syntax_pos..span_encoding..Span>>::specialized_decode
rustc_metadata::decoder::_<impl rustc_metadata..cstore..CrateMetadata>::imported_source_files
_<alloc..vec..Vec<T> as alloc..vec..SpecExtend<T, I>>::from_iter
_<core..iter..Map<I, F> as core..iter..iterator..Iterator>::fold
_<std..thread..local..LocalKey<T>>::with
rustc_typeck::check_crate
rustc::util::common::time
rustc::ty::query::plumbing::_<impl rustc..ty..context..TyCtxt<'a, 'gcx, 'tcx>>::try_get_with
rustc::dep_graph::graph::DepGraph::with_task_impl
rustc::ty::query::_<impl rustc..ty..query..config..QueryAccessors<'tcx> for rustc..ty..query..queries..typeck_item_bodies<'tcx>>::compute
rustc::ty::query::__query_compute::typeck_item_bodies
rustc_typeck::check::typeck_item_bodies
rustc::session::Session::track_errors
rustc::ty::query::_<impl rustc..ty..query..queries..typeck_tables_of<'tcx>>::ensure
rustc::ty::query::plumbing::_<impl rustc..ty..context..TyCtxt<'a, 'gcx, 'tcx>>::ensure_query
rustc::ty::query::plumbing::_<impl rustc..ty..context..TyCtxt<'a, 'gcx, 'tcx>>::try_get_with
rustc::dep_graph::graph::DepGraph::with_task_impl
rustc::ty::query::_<impl rustc..ty..query..config..QueryAccessors<'tcx> for rustc..ty..query..queries..typeck_tables_of<'tcx>>::compute

They might look okay but just uploaded if there's any chance to improve.

@namhyung
Copy link
Owner

You don't need to use xargs since it reads from stdin if no arg is given. :)

Anyway I also think it needs to simplify symbol like we do in C++. Following is some of my idea.

  • ignore type param in generic: A::foo<T> --> A::foo
  • simplify "impl" by removing type info: _<impl foo for bar> --> foo
  • remove former in "as": _<foo as bar> --> bar
  • convert .. to :: in _<...>

But I'm not 100% sure for this. Thoughts?

@honggyukim
Copy link
Collaborator Author

Looks better but not sure about it as I'm not familiar with Rust lang as of yet.

@quark-zju @ParkHanbum @taeguk Could you give us some thoughts for Rust symbol demangling as above?

@taeguk
Copy link
Contributor

taeguk commented Jan 21, 2019

  • remove former in "as": _<foo as bar> --> bar

About this idea, there are some problematic things:

// except.rs
trait Trait {
    fn new() -> Self;

    fn foo(&self) {
        println!("Trait::foo()");
    }
    fn bar(&self);
}

struct Struct {
    var1: i32,
    var2: bool
}

impl Struct {
    fn method(&self) {
        println!("Struct::method()");
    }
}

impl Trait for Struct {
    fn new() -> Struct {
        println!("Struct::new()");
        Struct { var1: 3, var2: true }
    }
    fn bar(&self) {
        println!("Struct::bar()");
    }
}

fn main() {
    let s: Struct = Trait::new();   // Struct::new()
    s.foo();    // Trait::foo()
    s.bar();    // Struct::bar()
    s.method(); // Struct::method()
}
$ rustc -Z instrument-mcount -g -A dead_code except.rs
$ uftrace ./except
Struct::new()
Trait::foo()
Struct::bar()
Struct::method()
# DURATION     TID     FUNCTION
            [ 80895] | std::rt::lang_start() {
            [ 80895] |   std::rt::lang_start::_{{closure}}() {
            [ 80895] |     except::main() {
            [ 80895] |       _<except..Struct as except..Trait>::new() {
   0.092 us [ 80895] |         core::fmt::Arguments::new_v1();
  95.423 us [ 80895] |       } /* _<except..Struct as except..Trait>::new */
            [ 80895] |       except::Trait::foo() {
   0.081 us [ 80895] |         core::fmt::Arguments::new_v1();
   3.435 us [ 80895] |       } /* except::Trait::foo */
            [ 80895] |       _<except..Struct as except..Trait>::bar() {
   0.070 us [ 80895] |         core::fmt::Arguments::new_v1();
   1.467 us [ 80895] |       } /* _<except..Struct as except..Trait>::bar */
            [ 80895] |       except::Struct::method() {
   0.075 us [ 80895] |         core::fmt::Arguments::new_v1();
   1.367 us [ 80895] |       } /* except::Struct::method */
 102.681 us [ 80895] |     } /* except::main */
            [ 80895] |     _<() as std..process..Termination>::report() {
            [ 80895] |       _<std..process..ExitCode as std..process..Termination>::report() {
   0.064 us [ 80895] |         std::sys::unix::process::process_common::ExitCode::as_i32();
   0.399 us [ 80895] |       } /* _<std..process..ExitCode as std..process..Termination>::report */
   0.592 us [ 80895] |     } /* _<() as std..process..Termination>::report */
 103.621 us [ 80895] |   } /* std::rt::lang_start::_{{closure}} */
 379.175 us [ 80895] | } /* std::rt::lang_start */

If applying @namhyung's suggestion to
_<except..Struct as except..Trait>::new() and _<except..Struct as except..Trait>::bar(), then they become except::Trait::new() and except::Trait::bar().
But I think it is bad because these results are different to the functions which actually called.

@quark-zju
Copy link

quark-zju commented Jan 21, 2019

I'm not an expert in this area. But the current Rust symbols are kind of Rust implementation details. See rust-lang/rfcs#2603. Things might change rapidly. I think it makes sense to not spend too much effort on things to be changed, and wait for the new, more standardized schema.

@honggyukim
Copy link
Collaborator Author

Hi @taeguk @quark-zju, thanks very much for your feedback. It seems to be more complicated than we thought. It'd be better to take time what to do after v0.9.2 release. Thanks a lot for your help!

@namhyung
Copy link
Owner

@taeguk do you think _<foo as bar> -> foo is more appropriate?

@quark-zju I don't know when it's finished but I think we still need to support older versions anyway. I agree that it should not spend too much effort but I'd like to make it more readable with a slight simplification if possible..

@lu-zero
Copy link

lu-zero commented Feb 15, 2019

There is rust-demangle that could be used for a more accurate demangling.

@namhyung
Copy link
Owner

@lu-zero thanks for the comment. We have two demangler - 'simple' demangler shows more compact, readable name while 'full' demangler shows accurate name. I'm talking about the simple demangler here how we can improve readability.

Based on the observation above, I think it'd be better using _<foo as bar> -> foo unless it's not ().

@lu-zero
Copy link

lu-zero commented Mar 4, 2019

Please notice that mangling rules will change soon

@honggyukim
Copy link
Collaborator Author

There is rust-demangle that could be used for a more accurate demangling.

As @lu-zero suggested, we can get some reference to implement rust demangler.

rustfilt also uses the same demangler.

@namhyung
Copy link
Owner

Current output is like below. And #1626 was filed for the new mangling scheme.

$ cat rust-symbols.txt | misc/demangler 
rustc_driver::driver::phase_2_configure_and_expand_inner::_{{closure}}
rustc_resolve::macros::_<impl syntax::ext::base::Resolver for rustc_resolve::Resolver<'a>>::visit_ast_fragment_with_placeholders
_<rustc_resolve::build_reduced_graph::BuildReducedGraphVisitor<'a, 'b>>::visit_item
_<alloc::vec::Vec<T>>::from_iter
rustc_resolve::build_reduced_graph::_<impl rustc_resolve::Resolver<'a>>::populate_module_if_necessary
rustc_resolve::macros::_<impl syntax::ext::base::Resolver for rustc_resolve::Resolver<'a>>::resolve_imports
rustc_driver::driver::phase_3_run_analysis_passes
core::ptr::real_drop_in_place
_<rustc_codegen_llvm::LlvmCodegenBackend>::join_codegen_and_link
_<F>::call_box
rustc_resolve::build_reduced_graph::_<impl rustc_resolve::Resolver<'a>>::populate_module_if_necessary
rustc_metadata::cstore_impl::_<impl rustc_metadata::cstore::CStore>::item_children_untracked
rustc_metadata::decoder::_<impl rustc_metadata::cstore::CrateMetadata>::each_child_of_item
_<rustc_metadata::decoder::DecodeContext<'a, 'tcx>>::specialized_decode
rustc_metadata::decoder::_<impl rustc_metadata::cstore::CrateMetadata>::imported_source_files
_<alloc::vec::Vec<T>>::from_iter
_<core::iter::Map<I, F>>::fold
rustc_resolve::macros::_<impl syntax::ext::base::Resolver for rustc_resolve::Resolver<'a>>::resolve_imports
rustc_resolve::resolve_imports::ImportResolver::resolve_imports
rustc_resolve::build_reduced_graph::_<impl rustc_resolve::Resolver<'a>>::populate_module_if_necessary
rustc_metadata::cstore_impl::_<impl rustc_metadata::cstore::CStore>::item_children_untracked
rustc_metadata::decoder::_<impl rustc_metadata::cstore::CrateMetadata>::each_child_of_item
_<rustc_metadata::decoder::DecodeContext<'a, 'tcx>>::specialized_decode
rustc_metadata::decoder::_<impl rustc_metadata::cstore::CrateMetadata>::imported_source_files
_<alloc::vec::Vec<T>>::from_iter
_<core::iter::Map<I, F>>::fold
_<std::thread::local::LocalKey<T>>::with
rustc_typeck::check_crate
rustc::util::common::time
rustc::ty::query::plumbing::_<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_get_with
rustc::dep_graph::graph::DepGraph::with_task_impl
rustc::ty::query::_<impl rustc::ty::query::config::QueryAccessors<'tcx> for rustc::ty::query::queries::typeck_item_bodies<'tcx>>::compute
rustc::ty::query::__query_compute::typeck_item_bodies
rustc_typeck::check::typeck_item_bodies
rustc::session::Session::track_errors
rustc::ty::query::_<impl rustc::ty::query::queries::typeck_tables_of<'tcx>>::ensure
rustc::ty::query::plumbing::_<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::ensure_query
rustc::ty::query::plumbing::_<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_get_with
rustc::dep_graph::graph::DepGraph::with_task_impl
rustc::ty::query::_<impl rustc::ty::query::config::QueryAccessors<'tcx> for rustc::ty::query::queries::typeck_tables_of<'tcx>>::compute

@lu-zero
Copy link

lu-zero commented Dec 18, 2023

Looks good! I'd avoid adding the _ maybe though.

@namhyung
Copy link
Owner

Yeah, now it shows _<foo as bar> as _<foo>, maybe we can convert _< to <.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants