dlopen 不尊重 `RTLD_LOCAL`?
dlopen doesn't respect `RTLD_LOCAL`?
我有 A.so
,它链接到其自己目录中的特定版本 libstdc++.so.6
(通过 rpath
设置为 $ORIGIN
)。
如果我 dlopen
A.so
一个人,它工作正常。
如果我dlopen
我的系统libstdc++.so.6
(不同版本)处于RTLD_LOCAL
模式,然后dlopen
A.so
OSError: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by A.so)
为什么 dlopen 不尊重 RTLD_LOCAL
?
Why doesn't dlopen respect RTLD_LOCAL
RTLD_LOCAL
并不代表你想的那样。来自 man dlopen
:
RTLD_LOCAL
This is the converse of RTLD_GLOBAL, and the default if
neither flag is specified. Symbols defined in this shared
object are not made available to resolve references in
subsequently loaded shared objects.
请注意,这没有关于加载程序正在加载的库。
加载程序将永远不会加载给定SONAME
的多个实例(除非您使用dlmopen
使用不同的链接器范围),所以当你dlopen
系统libstdc++.so.6
,那就是只有libstdc++.so.6
你会永远得到。当你稍后dlopen("A.so", ...)
时,运行时加载器:
- 寻找
A.so
依赖的库,发现libstdc++.so.6
在其中,发现已经加载了libstdc++.so.6
,所以它不会搜索,也不会加载另一个副本,
- 查找
A.so
需要的 版本 符号。正是在这一点上你得到了错误,因为 A.so
需要来自 libsstdc++.so.6
的 GLIBCXX_3.4.20
,并且因为已经加载的系统 libstdc++.so.6
较旧并且不提供 GLIBCXX_3.4.20
版本。
- 由于第 2 步失败,您的
dlopen
被拒绝。
请注意,您永远无法解析 libstdc++.so.6
中的 任何 符号(其中 RTLD_LOCAL
很重要);你在 之前就失败了。
现在,您可能试图做的是构建A.so
,使其可以动态加载到任意程序中,可能是使用libstdc++.so.6
的旧版本,无需强制最终用户更新系统 libstdc++.so.6
。不幸的是,这根本无法完成。
我有 A.so
,它链接到其自己目录中的特定版本 libstdc++.so.6
(通过 rpath
设置为 $ORIGIN
)。
如果我 dlopen
A.so
一个人,它工作正常。
如果我dlopen
我的系统libstdc++.so.6
(不同版本)处于RTLD_LOCAL
模式,然后dlopen
A.so
OSError: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by A.so)
为什么 dlopen 不尊重 RTLD_LOCAL
?
Why doesn't dlopen respect
RTLD_LOCAL
RTLD_LOCAL
并不代表你想的那样。来自 man dlopen
:
RTLD_LOCAL
This is the converse of RTLD_GLOBAL, and the default if
neither flag is specified. Symbols defined in this shared
object are not made available to resolve references in
subsequently loaded shared objects.
请注意,这没有关于加载程序正在加载的库。
加载程序将永远不会加载给定SONAME
的多个实例(除非您使用dlmopen
使用不同的链接器范围),所以当你dlopen
系统libstdc++.so.6
,那就是只有libstdc++.so.6
你会永远得到。当你稍后dlopen("A.so", ...)
时,运行时加载器:
- 寻找
A.so
依赖的库,发现libstdc++.so.6
在其中,发现已经加载了libstdc++.so.6
,所以它不会搜索,也不会加载另一个副本, - 查找
A.so
需要的 版本 符号。正是在这一点上你得到了错误,因为A.so
需要来自libsstdc++.so.6
的GLIBCXX_3.4.20
,并且因为已经加载的系统libstdc++.so.6
较旧并且不提供GLIBCXX_3.4.20
版本。 - 由于第 2 步失败,您的
dlopen
被拒绝。
请注意,您永远无法解析 libstdc++.so.6
中的 任何 符号(其中 RTLD_LOCAL
很重要);你在 之前就失败了。
现在,您可能试图做的是构建A.so
,使其可以动态加载到任意程序中,可能是使用libstdc++.so.6
的旧版本,无需强制最终用户更新系统 libstdc++.so.6
。不幸的是,这根本无法完成。