【问题标题】:Global symbol in static libstdc++.a is local in shared libstdc++.so静态 libstdc++.a 中的全局符号在共享 libstdc++.so 中是本地符号
【发布时间】:2015-07-25 17:16:42
【问题描述】:

在尝试使用__gcclibcxx_demangle_callback 作为__cxa_demangle 的非分配替代方案时,我遇到了一个给我带来麻烦的问题。当我静态链接libstdc++ 时,符号已定位,但当我动态链接时,g++ 报告:

undefined reference to `__gcclibcxx_demangle_callback'

奇怪的是,nm 将其列在一个而不是另一个:

me@compy:/lib$ nm libstdc++.a | grep demangle
0000543d T __cxa_demangle
0000550d T __gcclibcxx_demangle_callback
me@compy:/lib$ nm -D libstdc++.so | grep demangle
0004eabd T __cxa_demangle

readelf 的输出提示了原因 - 它在静态中是全局的,在共享中是局部的:

me@compy:/lib$ readelf -s libstdc++.a | grep demangle
   179: 0000543d   208 FUNC    GLOBAL DEFAULT    1 __cxa_demangle
   180: 0000550d    32 FUNC    GLOBAL DEFAULT    1 __gcclibcxx_demangle_callback
me@compy:/lib$ readelf -s libstdc++.so | grep demangle
  8313: 0004eb8d    32 FUNC    LOCAL  DEFAULT   12 __gcclibcxx_demangle_callback
 10871: 0004eabd   208 FUNC    GLOBAL DEFAULT   12 __cxa_demangle

将我的整个应用程序与libstdc++ 静态链接不是一种选择。

我的问题有两个:

  1. 为什么两者的可见性不同?
  2. 如何才能访问此符号?有没有办法动态获取它,或者仅针对该符号所在的目标文件静态链接?

【问题讨论】:

    标签: c++ linker g++ libstdc++


    【解决方案1】:

    首先,可见性不同,因为在这两者中,只有__cxa_demangle<cxxabi.h> 标头中声明。该标头包含一个#pragma GCC visibility push(default),它确保在使用-fvisibility=hidden 编译时,其中的所有声明都是可见的。

    其次,您可以静态链接到 libstdc++,或者链接到 libiberty。 libiberty 导出cplus_demangle_v3_callback,它使用与__gcclibcxx_demangle_callback 相同的底层函数。它只是没有任何参数检查,也没有选择所需的解组选项。你可以这样称呼它:

    template <typename F>
    struct lambda_caller
    {
        F f;
        constexpr lambda_caller(F f) : f(std::move(f)) {}
        static void call(const char* data, size_t length, void* self)
        {
            static_cast<lambda_caller*>(self)->f(data, length);
        }
    };
    
    if (!lambda_caller callback{[&](const char* data, size_t length) {
            ::write(STDERR_FILENO, data, length);
        }}; ::cplus_demangle_v3_callback(mangled_name, DMGL_PARAMS | DMGL_TYPES,
                                       &callback::call, &callback))
        throw std::invalid_argument
            "mangled_name is not validly mangled according to C++ ABI rules"};
    

    【讨论】:

      猜你喜欢
      • 2019-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-14
      • 1970-01-01
      • 2016-12-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多