我正在尝试使用GCC’s abi::__cxa_demangle
来解析从g++
生成的目标文件中导出的符号。但是,我不变得错误
mangled_name 不是C ++ ABI修改规则下的有效名称
以下是我如何调用该函数:
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()};
}
(省略错误处理;它出现在complete online demo。)
我测试过的符号来自这个小代码:
namespace foo {
template <typename T>
struct bar { bar() { } };
}
void baz(int x) { }
template struct foo::bar<int>;
通过g++ -c test.cpp; nm test.o | cut -d ' ' -f3
:
EH_frame1
__Z3bazi
__ZN3foo3barIiEC1Ev
__ZN3foo3barIiEC2Ev
我不确定GCC demangling API的用途是什么,如果它不能解码这些符号 - 它可以,但是,成功地解除了C ++ typeid
表示。例如。在测试代码typeid(foo::bar<int>*).name()
中写入将产生PN3foo3barIiEE
,而后者将被上述函数正确解构。
我做错了吗?如何从GCC对象文件中解压缩导出的符号?
答案 0 :(得分:3)
您的符号前面有太多下划线。我不确定原因,但是如果你检查C++filtjs,它会报告相同的事情 - 它们不是有效的Itanium ABI符号,前面有两个下划线但只有一个。在这种情况下,我会说nm
的输出不正确,而不是demangle函数是错误的。 Itanium ABI指定并且我知道Clang只使用一个下划线。
你知道吗,它确实说了一些我现在几乎可以阅读Itanium ABI错误名字的东西了。太多时间阅读Clang的LLVM IR输出。