6

I’m trying to use GCC’s abi::__cxa_demangle to demangle symbols exported from an object file that was produced by g++. However, I invariable get the error

mangled_name is not a valid name under the C++ ABI mangling rules

Here’s how I call the function:

std::string demangled(std::string const& sym) {
    std::unique_ptr<char, void(*)(void*)>
        name{abi::__cxa_demangle(sym.c_str(), nullptr, nullptr, nullptr), std::free};
    return {name.get()};
}

(Error handling omitted; it’s present in the complete online demo.)

The symbols I tested it with are obtained from this small code:

namespace foo {
    template <typename T>
    struct bar { bar() { } };
}

void baz(int x) { }

template struct foo::bar<int>;

via g++ -c test.cpp; nm test.o | cut -d ' ' -f3:

EH_frame1
__Z3bazi
__ZN3foo3barIiEC1Ev
__ZN3foo3barIiEC2Ev

I’m not really sure which purpose the GCC demangling API serves if it cannot demangle these symbols – it can, however, successfully demangle the C++ typeid representations. E.g. writing in the test code typeid(foo::bar<int>*).name() will yield PN3foo3barIiEE, which in turn is correctly demangled by the above function.

Am I doing something wrong? How can I demangle the exported symbols from a GCC object file?

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • If the object file targets ARM, say, then the name mangling scheme will be different. The fact that it's created by G++ does not guarantee a consistent name mangling scheme. However, what I'm really seeing is that those symbols have one too many underscores in front. Try cutting the front one off. – Puppy Jul 10 '13 at 14:17
  • @DeadMG Interesting, didn’t know that, but in my case it isn’t actually ARM. Still, this might explain it. The questions remain: what is `__cxa_demangle` supposed to solve, and how do I demangle those symbols. – Konrad Rudolph Jul 10 '13 at 14:19
  • Exactly what are you "feeding" into the demangle function? – Mats Petersson Jul 10 '13 at 14:19
  • @Mats The names as I get them above (of course?). – Konrad Rudolph Jul 10 '13 at 14:19
  • With the `__` at the beginning, or without? I think it may make a difference... – Mats Petersson Jul 10 '13 at 14:20
  • 5
    on what platform are you? I can vaguely remember somthing about macosx prepending an extra _ that you need to strip – PlasmaHH Jul 10 '13 at 14:25
  • @PlasmaHH: My answer clearly shows that there is an extra _ here. – Puppy Jul 10 '13 at 14:26
  • 1
    @DeadMG: But you also said: "I'm not sure why" – PlasmaHH Jul 10 '13 at 14:28
  • @Mats I tried both, actually. Neither works. I did *not* try removing just one leading underscore, as suggested by PlasmaHH. Hmm. It works. – Konrad Rudolph Jul 10 '13 at 14:59

1 Answers1

3

Your symbols have one too many underscores in front. I'm not sure why, but if you check C++filtjs, it reports the same thing- they are not valid Itanium ABI symbols with two underscores in front but are with just one. In this case, I would say that the output of nm is incorrect, not that the demangle function is wrong. The Itanium ABI specifies and I know that Clang uses just one underscore.

Y'know, it really says something that I can almost read Itanium ABI mangled names by now. Way too much time reading Clang's LLVM IR output.

Puppy
  • 144,682
  • 38
  • 256
  • 465