加载与同一静态链接的功能的两个共享库时,其功能是用来(Which function is used

2019-09-27 07:31发布

我在读书,并试图理解符号是如何被Linux中共享库内解决。 因此,这里是什么,我面对的是一个描述。

我使用的应用程序(APP),其可加载用户创建的共享库添加新功能。 我有两个这样的库,LIB_A.soLIB_B.so执行独立的事情,不依赖于其他工作。 他们是独立编制并基于编译参数( -fPIC ),就会显得它将使符号interposable(从我的课题研究)。 因此,多数符号将被默认出口。

现在,有一个LIB_ALIB_B使用都被编译并与每个库静态链接的这个共同的代码。 常见的代码不使用任何命名空间或静态函数,所以我假设他们也会被导出。 无论LIB_A和LIB_B负载和工作按预期在APP。

但是,如果有共同的代码中发现了一个错误,但只有LIB_A可以重新编译,因为它需要固定的代码。 我的问题是,当LIB_A重新编译拿起在公共代码这一变化,并在应用程序获取加载时,会不会有(不具有的两个LIB_A(有bug修复)和LIB_B通用代码单独副本bug修复),每个将利用各自的副本或将两者联系和分享的两个常见的代码版本中的一个? 有我的方式来发现使用调试器也许是符号的来源是什么?

刚要出人头地的时间回答问题,我不知道是哪个命令库将被加载,我不能重新编译LIB_B拿起变化,只有LIB_A。 我没有APP的源代码就知道它是如何动态加载的库。

我知道有一个很大的编译器标志,但假设它只是-fPIC ,没有-fvisibility-hidden-Wl,-Bsymbolic-fno-semantic-interposition标志设置。 将这些解决这个问题,如果有冲突?

我看着使用nm -D命令,我看到一些符号是W,这是否意味着如果使用一个静态与库建立了一个之前已经存在,它会使用现有的符号?

我一直在阅读文章和搜索,但是这个事情我不知道我100%确定下来。

编辑欲了解更多信息,我在按需运行时加载这些库。 这会改变使用任何dlopenRTLD_LOCAL VS RTLD_GLOBAL ? 从描述,RTLD_LOCAL似乎以防止全球加载符号,因此不会对库外部冲突或链接到其他的符号?

Answer 1:

会不会有(不具有bug修复)的两个LIB_A(有bug修复)和LIB_B通用代码单独副本

在没有-fvisibility=hidden (或其他类似的标志,你提)运行时链接程序将确保所有重复的符号被解析为相同的实现(在LIB_A或LIB_B)。 所以库将有效地共享代码。

有我的方式来发现使用调试器也许是符号的来源是什么?

一般来说,符号会从提供他们的第一装载库(LIB_A或LIB_B)服用。 图书馆将在他们中列出的顺序加载.dynamic可执行文件的部分(运行readelf -d app ,以确保或者干脆运行你的应用程序LD_DEBUG设置为可变的symbols )。 如果要强制LIB_A被首先加载,您可以设置LD_PRELOAD相应。

我知道有一个很大的编译器标志,但假设它只是-fPIC ,没有-fvisibility-hidden-Wl,-Bsymbolic-fno-semantic-interposition标志设置。 将这些解决这个问题,如果有冲突?

我想,你希望每个库使用它自己的常用符号的版本? 实现这一目标的最标准的方法是-fvisibility=hidden 。 这将防止常见的符号被导出,然后他们将静态解析到本地副本。 当然,那么你就需要找到和注释需要导出等功能。

-Bsymbolic也可以帮助,但这将强制所有本地解析引用也就是说你想能够将其限制在你感兴趣的符号的子集解决。而且它不太广泛的应用。

至于-fno-semantic-interposition ,我没有最近GCC在手,但我的印象是,它是编译器优化标志,一般也不能保证符号的本地分辨率。

我看着使用纳米-D命令,我看到一些符号是W,这是否意味着如果使用一个静态与库建立了一个之前已经存在,它会使用现有的符号?

不,运行时链接不采取象征的弱点考虑(至少在没有LD_DYNAMIC_WEAK环境变量 ,我不建议使用)。



文章来源: Which function is used when loading two shared libraries with same statically linked functions