如何 运行 现代 GNU/Linux 发行版中的旧二进制文件?

How to run an old binary on modern GNU/Linux distribution?

我正在尝试 运行 一个在 CentOS 6 上编译的旧 C++ 程序,在现代 GNU/Linux 发行版 (Gentoo Linux) 上。现在CentOS 6已经过时,推荐的库也已经过时,所以有必要为二进制文件提供工作环境。

我已经尝试使用 ldd 命令和一些脚本从二进制文件所需的 CentOS 6 复制所有必要的共享库。现在我有一个包含所有必需库的目录。但是,当我尝试 运行 我的程序 LD_LIBRARY_PATH="the directory with .so-files" 时,终端显示一条消息

$ LD_LIBRARY_PATH=`pwd`/lib ./my-program
Inconsistency detected by ld.so: dl-call-libc-early-init.c: 37: _dl_call_libc_early_init: Assertion `sym != NULL' failed!

所以它出于某种原因不想工作。如果不强制链接到旧的 .so,二进制文件也不会 运行(很明显)。我没有时间在现代 Linux 上重新编译我的程序或制作它的静态版本,因为它需要旧库,而且程序必须 运行 在我不维护的几台 PC 上。

有没有一种可靠的方法可以在没有容器或虚拟机的情况下 运行 现代 Linux 上的旧二进制文件?也许我的方法是正确的,但需要解决一些问题,或者我的方法是错误的,需要尝试其他方法。

如果你读到这一行,谢谢你的关注!

我附上了所需库的列表(ldd my-program 的输出):

linux-vdso.so.1 =>  (0x00007ffc26b40000)
librfftw.so.2 => /usr/lib64/librfftw.so.2 (0x00007f026f631000)
libfftw.so.2 => /usr/lib64/libfftw.so.2 (0x00007f026f3f8000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f026f1f4000)
libboost_thread-mt.so.5 => /usr/lib64/libboost_thread-mt.so.5 (0x00007f026efdf000)
libboost_system-mt.so.5 => /usr/lib64/libboost_system-mt.so.5 (0x00007f026eddc000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f026ebbf000)
libxml++-2.6.so.2 => /usr/lib64/libxml++-2.6.so.2 (0x00007f026e99c000)
libxml2.so.2 => /usr/lib64/libxml2.so.2 (0x00007f026e649000)
libglibmm-2.4.so.1 => /usr/lib64/libglibmm-2.4.so.1 (0x00007f026e3f4000)
libgobject-2.0.so.0 => /lib64/libgobject-2.0.so.0 (0x00007f026e1a8000)
libgthread-2.0.so.0 => /lib64/libgthread-2.0.so.0 (0x00007f026dfa4000)
librt.so.1 => /lib64/librt.so.1 (0x00007f026dd9c000)
libglib-2.0.so.0 => /lib64/libglib-2.0.so.0 (0x00007f026da85000)
libsigc-2.0.so.0 => /usr/lib64/libsigc-2.0.so.0 (0x00007f026d880000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f026d57a000)
libm.so.6 => /lib64/libm.so.6 (0x00007f026d2f6000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f026d0e0000)
libc.so.6 => /lib64/libc.so.6 (0x00007f026cd4c000)
/lib64/ld-linux-x86-64.so.2 (0x00007f026f864000)
libz.so.1 => /lib64/libz.so.1 (0x00007f026cb36000)
libgmodule-2.0.so.0 => /lib64/libgmodule-2.0.so.0 (0x00007f026c933000)

Is there a reliable way

没有。 :p

Is there a way to run an old binary on modern Linux without containers or virtual machines?

您可以 运行 使用旧链接器和库路径的程序。当您使用旧系统 chroot 时,您可以:

LD_LIBRARY_PATH=$PWD/lib $PWD/lib/ld-linux-x86-64.so.2 ./my-program

但请注意,如果 ./my-program 然后 运行 通过 fork+exec 进行任何操作,则可能会出现问题。您可以将 PATH 设置为 chroot 中的位置,但解释器仍然可能是错误的。所以如果它是一个简单的程序,它“通常可以工作”。

无论如何,如果不使用 docker 或普通 chroot,您可能想看看 proot 程序。