在 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 时不要忘记单引号
我想将 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 时不要忘记单引号