I'm trying to run an old C++ program, compiled on CentOS 6, on modern GNU/Linux distribution (Gentoo Linux). Nowadays CentOS 6 is outdated as well as suggested libraries, so it is necessary to provide working environment for the binary.
I already tried to copy all necessary shared libraries from CentOS 6 required by the binary using ldd
command and some script. Now I have a directory with all required libraries. However, when I'm trying to run my program with LD_LIBRARY_PATH="the directory with .so-files", terminal shows a message
$ 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 it doesn't want to work for some reason. Without forced linking to old .so's the binary doesn't run either (obviously). I don't have time to recompile my program on modern Linux or make static version of it, because it's require old libraries, and the program must run on few PCs which I don't maintain.
Is there a reliable way to run an old binary on modern Linux without containers or virtual machines? Maybe I'm on the right way but need to solve some issues, or I'm on a wrong way and need to try something else.
If you read until this line, thank you for attention!
I attach a list of required libraries (output of 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
No. :p
Is there a way to run an old binary on modern Linux without containers or virtual machines?
You can run the program using the old linker and with the library path. When you have a old system chroot, you can:
LD_LIBRARY_PATH=$PWD/lib $PWD/lib/ld-linux-x86-64.so.2 ./my-program
But note that if the ./my-program
will then run anything via fork
+exec
, there may be problems. You may set PATH
to the locations from chroot
, but still the interpreter could be the wrong one. So it "generally works" if it's a simple program.
Anyway if not with docker
or plain chroot
, you might want to see proot
program.