我正在开发一个更新应用程序,该应用程序必须能够在现有系统上运行,并且还必须由该现有系统上的另一个应用程序启动。
我正在使用一个共享库,该共享库本身使用OpenSSL,但是没有针对它进行链接。以前,我的更新应用程序与OpenSSL链接以解决此问题。但是现在由于二进制不兼容,我无法再链接到OpenSSL。现在,当我的应用程序在现有系统上启动时,由于没有加载OpenSSL,我收到一个undefined symbol
错误。请注意,我无法选择通过LD_PRELOAD
加载它,因为我无法更改启动更新应用程序的应用程序。
我曾考虑过通过dlopen
加载OpenSSL,希望共享库能够使用它。但是共享库在C构造函数(__attribute__((constructor (101))) void myConstructor()
中使用OpenSSL,即使我在另一个具有更高优先级的构造函数中调用dlopen
,动态装载程序似乎也已经在OpenSSL中搜索(失败了)。我的构造函数甚至都没有执行。
LD_BIND_NOW
未设置,所以我想知道为什么在调用构造函数之前发生undefined symbol
错误。
答案 0 :(得分:0)
我自己找到了解决方法。
问题在于共享库在主应用程序之前被初始化(即,调用了C构造函数)。设置环境变量LD_DEBUG=libs
时可以看到顺序。所以我自己创建了一个共享库。我将这个修订库链接到越野车库(-lbuggy -lfix
)后面,因为初始化过程大致(我不太了解规则)是按相反的加载顺序进行的。
现在,我能够像这样在我的修订库的C构造函数中加载OpenSSL:
void *p = dlopen("libssl.so.1.0.0", RTLD_LAZY | RTLD_GLOBAL | RTLD_NODELETE);
if(p)
dlclose(p);
标志RTLD_GLOBAL
确保其他库也可以使用OpenSSL。
标志RTLD_NODELETE
确保没有在dlclose
上卸载该库。
注意:当我的更新应用程序在具有OpenSSL 1.1的较新系统上运行并且可以正确链接到OpenSSL的共享库时,加载libssl.so.1.0.0
会失败,因为该系统上不存在旧的OpenSSL版本(嵌入)系统,需要节省磁盘空间)。如果OpenSSL 1.0仍然存在,则可能是一个问题。