关于 DSO 引用隐藏符号的警告到底意味着啥?
Posted
技术标签:
【中文标题】关于 DSO 引用隐藏符号的警告到底意味着啥?【英文标题】:What does exactly the warning mean about hidden symbol being referenced by DSO?关于 DSO 引用隐藏符号的警告到底意味着什么? 【发布时间】:2014-07-04 23:36:31 【问题描述】:我在将某些共享库与 g++ 链接时遇到问题。它给了我一个警告,例如:
hidden symbol XXX in YYY is referenced by DSO /usr/lib/...
我已经阅读了一些关于特定问题的相关问题,但我想整体理解它——这个警告是什么意思,原因是什么:
-
什么是 DSO?
什么是隐藏符号?
如果隐藏了,如何引用?
【问题讨论】:
DSO = 动态共享对象 【参考方案1】:什么是 DSO?
DSO 是一个动态共享对象,或者不太正式的shared library。
什么是隐藏符号?
隐藏符号是一个符号(即函数或数据对象的名称) 已使用隐藏链接编译,例如根据(特定于 GCC) 声明:
int x __attribute__ ((visibility ("hidden")));
如果x
在一个 DSO 中定义,则动态链接无法从一个 DSO 引用它
不同的 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
中的引用动态(即在运行时),因为S
在Y
中有隐藏链接。
我可以确认问题出在非共享对象上 [...][但是] 我没有在我的非共享对象中明确隐藏这些符号。
您可能没有明确标记非共享对象中隐藏的任何符号。根据它的构建方式,符号 默认情况下可能隐藏,除非明确标记否则。
假设非共享对象是libnonshared.a
,据称隐藏的符号是foo
。运行:
objdump -t libnonshared.a
获取有关libnonshared.a
中符号的信息。在输出中,查找 foo
的条目。它是否包含标签.hidden
? - 例如
0000000000000000 g F .text 000000000000000b .hidden foo
此条目说foo
是一个全局符号(标记为g
- 这就是链接器能够看到它的原因)但是它对于动态链接是隐藏的.
如果是这种情况,那么您需要修复libnonshared.a
的构建,以便它不会隐藏foo
。
如果没有,那我就难住了。
【讨论】:
我不明白你回答的最后一部分。如果某些 DSO 已经引用了隐藏符号,那么为什么问题出在 DSO 上? - 实际上,我可以确认问题出在非共享对象上,该对象定义了一些可能具有相同名称的符号,DSO 将其称为外部符号——它们是在另一个地方提供的。另外,我没有在我的非共享对象中明确隐藏这些符号。以上是关于关于 DSO 引用隐藏符号的警告到底意味着啥?的主要内容,如果未能解决你的问题,请参考以下文章
GLEW + cmake 链接失败“未定义对符号 glDrawElements 的引用”+“命令行中缺少 DSO”
在 Gradle 中,api 配置暴露了依赖关系,而实现却没有,这到底意味着啥?
[C/C++]_[初级]_[关于编译时出现有符号-无符号不匹配的警告-sizeof使用注意事项]