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

Using LD_PRELOAD mixed 64bit/32bit environment in Linux

我想将 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? 谢谢!

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

$ LD_PRELOAD=lib_init.so ./hello32

将在 /lib 中搜索 lib_init.so,而

$ LD_PRELOAD=lib_init.so ./hello64

将在 /lib64 中搜索

原来可以在设置LD_PRELOAD(或者设置文件/etc/ld.so.preload)的时候设置use $LIB。问题在于 $LIB 设置的值取决于您的 linux 分布。呃!

在我的有限测试中,我发现基于 Redhat 的系统将 $LIB 扩展到 "lib64"(对于 64 位应用程序)和 "lib"(对于 32 位应用程序)。

然而,在基于 debian 的发行版上,我发现 $LIB 扩展为 "lib/x86_64-linux-gnu" 用于 64 位应用程序和 "lib/i386-linux-gnu" 用于 32 位应用程序。我没能找到关于此的任何文档,但我已经对此进行了测试。

这意味着如果我有:

 $ LD_PRELOAD='/$LIB/lib_init.so'  ./hello64

在像 ubuntu 这样的基于 debian 的系统上,我有:

/lib/x86_64-linux-gnu/lib_init.so  (for 64bit apps)

/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 时不要忘记单引号