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

7
我想在现代GNU/Linux发行版(如Gentoo Linux)上运行一个旧的C++程序,该程序在CentOS 6上编译。现在CentOS 6和建议使用的库已经过时,因此需要为该二进制文件提供工作环境。
我已经尝试使用ldd命令和一些脚本从CentOS 6中复制二进制文件所需的所有共享库。现在我有了一个包含所有必要库的目录。但是,当我尝试使用LD_LIBRARY_PATH="带有.so文件的目录"来运行我的程序时,终端显示一个消息。
$ 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)

4
使用 chroot 或 docker run centos6 安装 CentOS 6,并运行该二进制文件。无论如何都要使用旧版本解释器来运行该二进制文件,可以使用以下命令:LD_LIBRARY_PATH=$PWD/lib $PWD/lib/ld-linux-x86-64.so.2 ./my-program - KamilCuk
1
@KamilCuk 非常感谢!我已经在使用 LXD 容器,但是我的同事们还没有准备好使用 LXD/Docker/chroot。您建议使用旧的链接器已经解决了问题。 - Sergej Solov'yov
1个回答

4

有可靠的方法吗?

没有:p

有没有一种在现代Linux上运行旧二进制文件的方法,而不使用容器或虚拟机?

您可以使用旧链接器和库路径来运行程序。当您拥有旧系统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程序。


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