为何dlopen重用以前加载的符号的地址?

问题描述 投票:0回答:1

我刚刚调试了一个奇怪的问题,其中有两个库,我们将其称为libA.so和libB.so

应用程序dlopens libA.so是一个瘦库,然后加载实际的实现libB.so。

两个dlopens都使用RTLD_NOW选项调用,没有其他选项传递。

并且两个库都使用相同的记录器模块,其中记录器的状态存储在全局变量中,因为这两个库都使用相同的记录器并静态链接到它们,因此它们中的全局变量具有相同的名称。

加载libB时,两个全局变量位于相同的地址并且发生冲突。因此,动态链接器重新使用了变量的地址,以在libB中使用相同的变量。]​​>

如果很重要,此变量是在.cpp文件中深入定义的,我不确定C和C ++之间的链接是否不同。

读取dlopen's documentation时说:

RTLD_GLOBAL

此库定义的符号将可用于以后加载的库的符号解析。

RTLD_LOCAL

这与RTLD_GLOBAL相反,如果未指定任何标志,则为默认值。此库中定义的符号不可用于解析后续加载的库中的引用。

因此,RTLD_LOCAL应该是默认值,即解析libB的符号时不应使用libA的符号。但它仍在发生。为什么?

作为一种解决方法,我在此全局变量中添加了visible(“ hidden”)选项以避免导出。并提出了一张票以默认隐藏所有符号,因此将来不会发生这种碰撞,但是我仍然想知道为什么在不应该发生这种情况。

我刚刚调试了一个奇怪的问题,其中有两个库,我们将其称为libA.so和libB.so。应用程序dlopens libA.so是一个瘦库,然后加载实际的libB.so ...]]

linux gcc shared-libraries dynamic-linking
1个回答
0
投票

回答此问题的关键是主可执行文件exports

在其动态符号表中是否具有相同的符号。也就是说,输出的结果是:
© www.soinside.com 2019 - 2024. All rights reserved.