在Linux中使用LD_PRELOAD混合64位/32位环境

6

我想将LD_PRELOAD设置为指向一个共享库,以便我可以运行64位或32位应用程序。显然,共享库和可执行文件的位数必须匹配。

$ LD_PRELOAD=/lib64/lib_init.so ./hello32
ERROR: ld.so: object '/lib64/lib_init.so' from LD_PRELOAD cannot be preloaded (wrong ELF class: ELFCLASS64): ignored

其中hello32是一个32位应用程序。世界上有些页面说我应该能够执行以下操作:

$ LD_PRELOAD='/$LIB/lib_init.so' ./hello32
ERROR: ld.so: object '/$LIB/lib_init.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored

$LIB将根据应用程序是32位还是64位自动在lib和lib64之间切换。但是很明显这不起作用。

有什么诀窍可以让它工作吗?LD_PRELOAD_32,LD_PRELOAD_64?谢谢!


我会使用一个包装脚本,检查应用程序的位数,并相应地设置库。 - user3159253
1
尽量不要指定完整路径。动态链接器会选择正确的路径,例如 LD_PRELOAD=lib_init.so。 - kofemann
@kofemann,那正是我正在寻找的。您能否将其作为答案提交,以便我批准它。 - Robert McLay
我相信你记得的$LIB是来自于man ld.so并搜索Rpath token expansion。在链接时设置rpath时可以使用变量。而rpath是动态链接器在程序启动时查找库文件的位置。 - Zan Lynx
2个回答

9

通过指定库的完整路径,您不会让动态链接器根据二进制架构调整其搜索路径。只需定义库名称,让链接器为您选择正确的库。例如:

$ LD_PRELOAD=lib_init.so ./hello32

将会在/lib目录下搜索lib_init.so

$ LD_PRELOAD=lib_init.so ./hello64

将在/lib64中进行搜索


5
原来在设置LD_PRELOAD(或设置文件/etc/ld.so.preload)时可以使用$LIB。问题是$LIB的值取决于您的Linux发行版。在我的有限测试中,我发现基于Redhat的系统对于64位应用程序,$LIB扩展为“lib64”,对于32位应用程序,$LIB扩展为“lib”。但是,在基于Debian的发行版上,我发现$LIB会扩展为“lib / x86_64-linux-gnu”以用于64位应用程序,而对于32位应用程序,则会扩展为“lib / i386-linux-gnu”。我没有找到任何关于此的文档,但我已进行了测试。这意味着如果我有:
 $ LD_PRELOAD='/$LIB/lib_init.so'  ./hello64

在像Ubuntu这样的基于Debian系统上,我有以下内容:
/lib/x86_64-linux-gnu/lib_init.so  (for 64bit apps)

and

/lib/i386-linux-gnu/lib_init.so  (for 32bit apps)

这将在基于Ubuntu的Linux计算机上正常工作。

否则,在基于Redhat的发行版上,您需要:

  /lib64/lib_init.so and /lib/lib_init.so

适用于64位和32位应用程序。

使用LD_PRELOAD = '/ $LIB / lib_init.so'的优点是您不依赖于$ LD_LIBRARY_PATH的值。

设置LD_PRELOAD中的$ LIB时,请不要忘记单引号


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接