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.
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".
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
See this thread: https://gcc.gnu.org/ml/gcc-patches/2016-11/msg00359.html
Working on this.
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.
Created attachment 9978 [details] the patch the patch; needs a test case
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);
Wow, thanks Mark. I'm glad you pointed that out, I had totally missed it.
https://sourceware.org/pipermail/gdb-patches/2023-March/198103.html
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>
Fixed.