6

我正在尝试使用GCCabi::__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()};
}

(省略了错误处理;它出现在完整的在线演示中。)

我测试它的符号是从这个小代码中获得的:

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 解组 API 的用途是什么——但是,它可以成功地对 C++typeid表示进行解组。例如,在测试代码中编写typeid(foo::bar<int>*).name()会 yield PN3foo3barIiEE,而这又会被上述函数正确地分解。

难道我做错了什么?如何从 GCC 目标文件中解开导出的符号?

4

1 回答 1

3

您的符号前面有太多下划线。我不知道为什么,但是如果你检查C++filtjs,它会报告同样的事情——它们不是有效的 Itanium ABI 符号,前面有两个下划线,但只有一个。在这种情况下,我会说 的输出nm不正确,而不是 demangle 函数错误。Itanium ABI 指定并且我知道 Clang 只使用一个下划线。

你知道,它确实说明了我现在几乎可以读懂 Itanium ABI 混乱名称的内容。阅读 Clang 的 LLVM IR 输出的时间太多了。

于 2013-07-10T14:20:43.913 回答