Page MenuHomePhabricator

[lldb] Enable Rust v0 symbol demangling
AcceptedPublic

Authored by asm on Thu, Jun 10, 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.Thu, Jun 10, 1:16 PM
asm requested review of this revision.Thu, Jun 10, 1:16 PM
Herald added a project: Restricted Project. · View Herald TranscriptThu, Jun 10, 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.Thu, Jun 10, 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.Thu, Jun 10, 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.Fri, Jun 11, 9:44 AM
asm marked an inline comment as done.

code style fixes, use modern log

teemperor accepted this revision.Fri, Jun 11, 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.Fri, Jun 11, 9:53 AM
asm added a comment.Fri, Jun 11, 10:24 AM

And thank you for the quick review!

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

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

Yes, good to go!