Bug 20367 - add further Rust demangling
Summary: add further Rust demangling
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: rust (show other bugs)
Version: unknown
: P2 normal
Target Milestone: 14.1
Assignee: Tom Tromey
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-07-13 19:31 UTC by Tom Tromey
Modified: 2023-03-20 13:58 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
the patch (791 bytes, text/plain)
2017-04-09 00:22 UTC, Tom Tromey
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Tom Tromey 2016-07-13 19:31:34 UTC
It turns out that maybe Rust needs demangling beyond what the
C++ demangler does.  See:

http://git.kernel.org/cgit/linux/kernel/git/tip/tip.git/commit/?id=cae15db74999edb96dd9f5bbd4d55849391dd92b

This should be done in libiberty alongside the C++ and D
demanglers.
Comment 1 Tom Tromey 2016-07-14 18:33:52 UTC
It's not entirely clear this is needed yet.

It won't affect minsym demangling because that is always shadowed by
the C++ demangler.

It won't affect DWARF demangling much (if at all) because due to
bug 20162 we're going to reject most linkage names from DWARF anyway.

However, still nice-to-have, in that we could add a new mode to
c++filt, nm -C, etc.  Also it would affect "demangle".
Comment 2 Tom Tromey 2016-09-13 14:07:36 UTC
I wonder if we could have the demangler's c++ mode ignore
rustc-generated identifiers.  (I'd have to check the spec.)

Also there was this patch:
https://github.com/rust-lang/rust/pull/36059/files
Comment 3 Tom Tromey 2016-11-11 17:24:12 UTC
See this thread:

https://gcc.gnu.org/ml/gcc-patches/2016-11/msg00359.html
Comment 4 Tom Tromey 2016-11-18 18:51:46 UTC
Working on this.
Comment 5 Tom Tromey 2017-04-09 00:20:39 UTC
I have a patch for this but I haven't been able to find a situation
where it helps.

It doesn't help minimal symbols, because gdb thinks those are always
C++ symbols.  There was a gdb bug on file for this, for Java, for a
long time; but it's difficult to argue that it is really a gdb bug
as any fix would seem to involve using debug symbols to interpret
minimal symbol names, which seems like an inversion at least.
(IMO Rust should not use a mangling that is close to
C++, but that's how it is for now.)

On the other hand, for DWARF symbols, the ones that are likely
to be affected are all emitted in a funny way, with names like "{{impl}}"
embedded.

E.g.:

    <54>   DW_AT_linkage_name: (indirect string, offset: 0x84): _ZN2bc8{{impl}}4what15__STATIC_FMTSTRE

There's a Rust compiler bug on file for this.
Comment 6 Tom Tromey 2017-04-09 00:22:19 UTC
Created attachment 9978 [details]
the patch

the patch; needs a test case
Comment 7 Mark Wielaard 2017-04-09 09:33:38 UTC
I think in rust_sniff_from_mangled_name () you need to use the new rust_is_mangled () or rust_demangle () from libiberty. See the documentation in demangle.h:

/* Returns non-zero iff MANGLED is a rust mangled symbol.  MANGLED must
   already have been demangled through cplus_demangle_v3.  If this function
   returns non-zero then MANGLED can be demangled (in-place) using
   RUST_DEMANGLE_SYM.  */
extern int
rust_is_mangled (const char *mangled);

/* Demangles SYM (in-place) if RUST_IS_MANGLED returned non-zero for SYM.
   If RUST_IS_MANGLED returned zero for SYM then RUST_DEMANGLE_SYM might
   replace characters that cannot be demangled with '?' and might truncate
   SYM.  After calling RUST_DEMANGLE_SYM SYM might be shorter, but never
   larger.  */
extern void
rust_demangle_sym (char *sym);

/* Demangles MANGLED if it was GNU_V3 and then RUST mangled, otherwise
   returns NULL. Uses CPLUS_DEMANGLE_V3, RUST_IS_MANGLED and
   RUST_DEMANGLE_SYM.  Returns a new string that is owned by the caller.  */
extern char *
rust_demangle (const char *mangled, int options);
Comment 8 Tom Tromey 2017-04-09 13:35:38 UTC
Wow, thanks Mark.  I'm glad you pointed that out, I had totally missed it.
Comment 10 Sourceware Commits 2023-03-20 13:53:46 UTC
The master branch has been updated by Tom Tromey <tromey@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=6e7eef72164c00d6a5a7b0bce9fa01f5481f33cb

commit 6e7eef72164c00d6a5a7b0bce9fa01f5481f33cb
Author: Tom Tromey <tom@tromey.com>
Date:   Sun Mar 19 09:13:10 2023 -0600

    Use rust_demangle to fix a crash
    
    PR rust/30211 points out a crash caused by a particular completion.
    This turns out to happen because a Rust minsym winds up in a
    C++-specific path in strncmp_iw_with_mode, which ultimately causes the
    completer to pass invalid arguments to string::append.
    
    This patch fixes the bug by reordering the language constants so that
    Rust comes before C++, and then using rust_demangle.  This ensures
    that minsyms are correctly marked as "Rust", avoiding this code and
    thus the crash.
    
    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=20367
    Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30211
    Reviewed-By: Andrew Burgess <aburgess@redhat.com>
Comment 11 Tom Tromey 2023-03-20 13:58:27 UTC
Fixed.