This is an archive of the discontinued LLVM Phabricator instance.

[lldb] Enable Rust v0 symbol demangling
ClosedPublic

Authored by asm on Jun 10 2021, 1:16 PM.

Details

Summary

Rust's v0 name mangling scheme [1] is easy to disambiguate from other
name mangling schemes because symbols always start with _R. The llvm
Demangle library supports demangling the Rust v0 scheme. Use it to
demangle Rust symbols.

Added unit tests that check simple symbols. Ran LLDB built with this
patch to debug some Rust programs compiled with the v0 name mangling
scheme. Confirmed symbol names were demangled as expected.

Note: enabling the new name mangling scheme requires a nightly
toolchain:

$ cat main.rs
fn main() {
    println!("Hello world!");
}
$ $(rustup which --toolchain nightly rustc) -Z symbol-mangling-version=v0 main.rs -g
$ /home/asm/hacking/llvm/build/bin/lldb ./main --one-line 'b main.rs:2'
(lldb) target create "./main"
Current executable set to '/home/asm/hacking/llvm/rust/main' (x86_64).
(lldb) b main.rs:2
Breakpoint 1: where = main`main::main + 4 at main.rs:2:5, address = 0x00000000000076a4
(lldb) r
Process 948449 launched: '/home/asm/hacking/llvm/rust/main' (x86_64)
warning: (x86_64) /lib64/libgcc_s.so.1 No LZMA support found for reading .gnu_debugdata section
Process 948449 stopped
* thread #1, name = 'main', stop reason = breakpoint 1.1
    frame #0: 0x000055555555b6a4 main`main::main at main.rs:2:5
   1    fn main() {
-> 2        println!("Hello world!");
   3    }
(lldb) bt
error: need to add support for DW_TAG_base_type '()' encoded with DW_ATE = 0x7, bit_size = 0
* thread #1, name = 'main', stop reason = breakpoint 1.1
  * frame #0: 0x000055555555b6a4 main`main::main at main.rs:2:5
    frame #1: 0x000055555555b78b main`<fn() as core::ops::function::FnOnce<()>>::call_once((null)=(main`main::main at main.rs:1), (null)=<unavailable>) at function.rs:227:5
    frame #2: 0x000055555555b66e main`std::sys_common::backtrace::__rust_begin_short_backtrace::<fn(), ()>(f=(main`main::main at main.rs:1)) at backtrace.rs:125:18
    frame #3: 0x000055555555b851 main`std::rt::lang_start::<()>::{closure#0} at rt.rs:49:18
    frame #4: 0x000055555556c9f9 main`std::rt::lang_start_internal::hc51399759a90501a [inlined] core::ops::function::impls::_$LT$impl$u20$core..ops..function..FnOnce$LT$A$GT$$u20$for$u20$$RF$F$GT$::call_once::h04259e4a34d07c2f at function.rs:259:13
    frame #5: 0x000055555556c9f2 main`std::rt::lang_start_internal::hc51399759a90501a [inlined] std::panicking::try::do_call::hb8da45704d5cfbbf at panicking.rs:401:40
    frame #6: 0x000055555556c9f2 main`std::rt::lang_start_internal::hc51399759a90501a [inlined] std::panicking::try::h4beadc19a78fec52 at panicking.rs:365:19
    frame #7: 0x000055555556c9f2 main`std::rt::lang_start_internal::hc51399759a90501a [inlined] std::panic::catch_unwind::hc58016cd36ba81a4 at panic.rs:433:14
    frame #8: 0x000055555556c9f2 main`std::rt::lang_start_internal::hc51399759a90501a at rt.rs:34:21
    frame #9: 0x000055555555b830 main`std::rt::lang_start::<()>(main=(main`main::main at main.rs:1), argc=1, argv=0x00007fffffffcb18) at rt.rs:48:5
    frame #10: 0x000055555555b6fc main`main + 28
    frame #11: 0x00007ffff73f2493 libc.so.6`__libc_start_main + 243
    frame #12: 0x000055555555b59e main`_start + 46
(lldb)

[1]: https://github.com/rust-lang/rust/issues/60705

Diff Detail

Event Timeline

asm created this revision.Jun 10 2021, 1:16 PM
asm requested review of this revision.Jun 10 2021, 1:16 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 10 2021, 1:16 PM

This seems reasonable to me, but I'll leave this open for a while in case someone that knows more about Rust mangling shows up. Otherwise I'll accept this next week.

lldb/source/Core/Mangled.cpp
213

Please use LLDB_LOG in new code: LLDB_LOG(log, "demangled rustv0: {0} -> \"{1}\"", M, demangled_cstr); (same in the line below).

(The code above just didn't get updated yet)

lldb/unittests/Core/MangledTest.cpp
72

Could you do me a favour and change your test functions to LLDB's code style, so mangled_name as a variable name instead of MangledName and so on.

I'm aware the rest of the file is already using LLVM code style, but I think that's was just an oversight. I'll probably change the code style in this file to LLDB's and it would keep the git history a bit simpler.

asm added inline comments.Jun 10 2021, 2:43 PM
lldb/unittests/Core/MangledTest.cpp
72

Sure no problem. This is my first contribution to LLVM. I just mimicked the code around.

Just to check I understand. You're looking for something like this?

ConstString manged_lname("_RRR");
Mangled the_mangled(mangled_name);
ConstString the_demangled = the_mangled.GetDemangledName();

EXPECT_STREQ("", the_demangled.GetCString());
teemperor added inline comments.Jun 10 2021, 2:48 PM
lldb/unittests/Core/MangledTest.cpp
72

Jepp, that's the LLDB code style! Thank you!

Once teemperor's issues are resolved this looks good to me!

asm updated this revision to Diff 351481.Jun 11 2021, 9:44 AM
asm marked an inline comment as done.

code style fixes, use modern log

teemperor accepted this revision.Jun 11 2021, 9:53 AM

LGTM, thanks! (And congrats on your first patch)

I'll land this for you next week just to give the others another chance to take a look.

This revision is now accepted and ready to land.Jun 11 2021, 9:53 AM
asm added a comment.Jun 11 2021, 10:24 AM

And thank you for the quick review!

clayborg accepted this revision.Jun 11 2021, 11:22 AM
asm added a comment.Jun 18 2021, 11:50 AM

@teemperor @clayborg Is this good to go? :)

Yes, good to go!

This revision was landed with ongoing or failed builds.Jun 21 2021, 9:20 AM
This revision was automatically updated to reflect the committed changes.