linux - 由于 librpmio.so 导致 Lua API 符号冲突

标签 linux lua shared-libraries ld rpm

如果我还必须链接到 RPM 库——特别是 lirpmio.so,我就很难运行一个使用 Lua(5.2 版)的程序。这是一个大型应用程序的一部分,该应用程序包含多个也使用 Lua 的共享库。

潜在的问题是我们使用的 librpmio.so 版本(4.4.X)中嵌入了一个 Lua 解释器,它没有隐藏 Lua 代码中包含的全局符号。 Lua 的 rpmio 版本 (5.0.2) 比我们使用的 Lua (5.2.x) 旧,因此它们不能完全互换。

到目前为止,我无法让我们自己的 Lua 代码和 RPM API 调用 正常工作。像 lua_pushlstring() 这样的 Lua API 将绑定(bind) liblua.so 或 lirpmio.so 中最先出现在加载模块链中的那个。如果我早些时候在链接器命令行上指定 -llua,那么我们所有的代码都可以正常工作,但对 RPM API 的调用最终会崩溃。如果 -lrpmio 早于我们的代码最终将崩溃,因为一些 Lua 调用最终使用 librpmio 的 Lua 副本。

我尝试对 liblua. 中的符号进行版本控制,以便我们使用这样的版本脚本进行构建:

LUA_5.2 {
    global:
            lua_*;
            luaL_*;

    local: *;
};

但这还不够,因为 librpmio.so 使用未版本化的符号,并且上面的版本脚本创建了符号的 LUA_5.2 版本加上“默认”版本。运行时绑定(bind)似乎更倾向于 liblua.so 中的未版本化符号而不是 lirpmio.so,即使前者在链中更早:

 19075: symbol=lua_pushlstring;  lookup in file=output/Linux64/bin/myapp [0]
 19075: symbol=lua_pushlstring;  lookup in file=/home/output/Linux64/lib/lib1.so [0]
 19075: symbol=lua_pushlstring;  lookup in file=/home/output/Linux64/lib/lib2.so [0]
 19075: symbol=lua_pushlstring;  lookup in file=/home/output/Linux64/lib/lib3.so [0]
 19075: symbol=lua_pushlstring;  lookup in file=/home/lib/libwx_base-2.8.so.0 [0]
 19075: symbol=lua_pushlstring;  lookup in file=/home/lib/libsqlite.so [0]
 19075: symbol=lua_pushlstring;  lookup in file=/home/lib/libssl.so.0.9.8 [0]
 19075: symbol=lua_pushlstring;  lookup in file=/home/lib/libcrypto.so.0.9.8 [0]
 19075: symbol=lua_pushlstring;  lookup in file=/lib64/libacl.so.1 [0]
 19075: symbol=lua_pushlstring;  lookup in file=/usr/lib64/librpm-4.4.so [0]
 19075: symbol=lua_pushlstring;  lookup in file=/home/lib/liblua.so [0]
 19075: binding file /usr/lib64/librpmio-4.4.so [0] to /home/lib/liblua.so [0]: normal symbol `lua_pushlstring'

请注意最后一行 - 它正在针对我的 liblua 解决 librpmio 中 lua_pushlstring 的绑定(bind)。

我可以通过设置 -Bsymbolic 来解决这个问题librpmio.so 上的标志,但这是我们无法控制的系统库,谁知道可能会导致什么其他问题。我想如果我可以在我的 liblua.so 中消除每个 Lua 符号的默认版本的创建,我可能能够解决这个问题,但我一直无法弄清楚如何从版本脚本中做到这一点。 GNU version script文档仅显示如何通过 __asm__ 指令执行此操作。

除了创建一个包含如下一堆行的文件并将其与我的 Lua 构建链接之外,还有其他想法吗?

__asm__(".symver lua_pushlstring,lua_pushlstring@LUA_5.2");

最佳答案

为了那些在搜索中遇到我的问题的人,我能够在不对我们的 Lua 源副本进行大量更改的情况下解决问题的唯一方法是动态加载所有 RPM 库。

用于对所有 Lua 符号进行版本控制而不让它们与未版本控制的符号匹配的 __asm__ 技术要求 __asm__ 指令位于定义符号的源模块中,这意味着需要为大量 Lua 文件打补丁。

我们只需要 12-15 RPM API,所以我想到的解决方案是使用 dlopen() 动态加载 lirpmio、librpm 和 lirpmdb(后者仅存在于 RPM <= 4.5 中)共享库。调用 dlopen() 时,我为标志指定了 RTLD_NOW|RTLD_LOCAL|RTLD_DEEPBIND。这会导致在内部解析 RPM 库中的 Lua(和其他)符号。

我必须使用 dlsym() 来获取我们使用的任何 RPM API 的地址,但至少这可以防止 librpmio 的 Lua 与我们较新的 Lua 发生冲突。

关于linux - 由于 librpmio.so 导致 Lua API 符号冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14901119/

相关文章:

cocoa - OS X 原生安装上可用的库列表?

c - 程序无法加载共享库GCC

linux - 关于同源中断的一些事情

c++ - 如何解决我在尝试通过 C++ 执行 Lua 文件时遇到的这个错误?

java - 像 Linux 终端一样分割字符串

string - Lua:在分隔字符串中查找标记

lua - 在lua脚本中按降序获取 key 列表

linux - 加载共享库时出错 --> 添加到 LD_LIBRARY_PATH?

linux - Bash:仅使用参数扩展查找和替换

检查特定 Linux 命令是否仍在运行的 Python 脚本