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?
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.