gcc 关于DSO引用隐藏符号的警告的确切含义是什么?

7eumitmz  于 2022-11-12  发布在  其他
关注(0)|答案(2)|浏览(179)

我有一个问题链接一些共享库与g++。它给我一个警告,如:

hidden symbol XXX in YYY is referenced by DSO /usr/lib/...

我已经阅读了一些关于特定问题的相关问题,但我想从整体上了解它--这个警告意味着什么,原因是什么:
1.什么是DSO?
1.什么是隐藏符号?
1.如果它是隐藏的,如何引用它?

rjee0c15

rjee0c151#

什么是DSO?

  • DSO* 是一个 * 动态共享对象 *,或者更通俗地说是一个 * 共享库 *。
    什么是隐藏符号?
  • hidden symbol* 是用 hidden linkage 编译的符号(即函数或数据对象的名称),例如,按照(GCC特定)声明:
int x __attribute__ ((visibility ("hidden")));

如果在一个DSO中定义了x,则动态链接无法从另一个DSO引用它。链接程序可以看到x(它不是static),但它不可用于 * 动态 * 链接。文档here

如果它是隐藏的,如何引用它?

这是不可能的,这就是你被警告的。例如,链接时间警告:
/usr/lib/libc_nonshared.a(stat.oS)中的隐藏符号'stat'被DSO引用
是告诉您链接中的DSO引用符号stat,链接器可以在/usr/lib/libc_nonshared.a中找到stat的定义,但(很明显)该定义不在引用它的DSO中,并且不能从该DSO中引用,因为它是隐藏的。
如果未正确建立问题DSO以用作DSO,则会出现此问题。请参阅this example并遵循后续操作以获得解决方案。

继续OP的随访

如果隐藏符号已经被某个DSO引用,那么为什么DSO会出现问题?
链接器说:
DSO X包含对符号S的引用。我可以找到符号S的定义是另一个链接模块Y,但该定义将无法 * 动态 *(即 * 在运行时 *)满足X中的引用,因为SY中具有隐藏链接。
我可以确认这个问题是由一个非共享对象引起的[...][但是]我没有显式地在我的非共享对象中隐藏这些符号。
您可能未在非共享对象中显式标记任何隐藏符号。根据生成方式的不同,符号可能默认为隐藏,除非显式标记 * 否则 *。
假设非共享对象是libnonshared.a,而所谓的隐藏符号是foo。运行:

objdump -t libnonshared.a

以获取有关libnonshared.a中符号的信息。在输出中,查找foo的条目。它是否包含标记.hidden?-例如。

0000000000000000 g     F .text  000000000000000b .hidden foo

这个条目说foo是一个全局符号(标记为g-这就是为什么链接器能够看到它)* 但是 * 它对于 * 动态 * 链接是隐藏的。
如果事实证明是这样的话,那么你需要去修复libnonshared.a的构建,这样它就不会隐藏foo

tvokkenx

tvokkenx2#

这与Mike的精彩回答相差近十年,我想提供一个简短的答案,可能会在未来对其他人有所帮助:

发生此错误时会发生什么情况:

1.您正在链接的动态库包含正在由另一个库解析的符号
1.如果解析符号的库是静态的(.a),则会发生此错误
1.尝试将解析库重新创建为动态库(.so)

我遇到此问题的一个具体示例:

1.我创建了一个使用一些OpenCV函数的动态库,因此有一些OpenCV符号
1.我链接了OpenCV库来解析动态库中的符号,但我的OpenCV库是静态的,这导致了原始帖子中描述的错误。
1.我重新编译了OpenCV,这次将库创建为动态的
1.我尝试用我的动态库和新创建的OpenCV动态库重新编译我的程序
1.轰,错误不再出现。
祝你好运!

相关问题