这个问题老了,其他答案也老了。“受雇的俄罗斯人”的回答是非常好的和信息丰富的,但它只有在你有源代码的情况下才有效。如果你不这样做,那时候的选择是非常棘手的。幸运的是,现在我们对这个问题有了一个简单的解决方案(正如他在回复中评论的那样),使用patchelf。你所要做的就是:
$ ./patchelf --set-interpreter /path/to/newglibc/ld-linux.so.2 --set-rpath /path/to/newglibc/ myapp
在那之后,你可以执行你的文件:
$ ./myapp
No need to chroot or manually edit binaries, thankfully. But remember to backup your binary before patching it, if you're not sure what you're doing, because it modifies your binary file. After you patch it, you can't restore the old path to interpreter/rpath. If it doesn't work, you'll have to keep patching it until you find the path that will actually work... Well, it doesn't have to be a trial-and-error process. For example, in OP's example, he needed GLIBC_2.3, so you can easily find which lib provides that version using strings:
$ strings /lib/i686/libc.so.6 | grep GLIBC_2.3
$ strings /path/to/newglib/libc.so.6 | grep GLIBC_2.3
理论上,第一个grep会是空的,因为系统libc没有他想要的版本,而第二个grep应该输出glibc2.3,因为它有myapp正在使用的版本,所以我们知道可以使用该路径修补我们的二进制文件。如果你得到一个分割错误,阅读末尾的说明。
当你尝试在linux中运行二进制文件时,二进制文件会尝试加载链接器,然后加载库,它们都应该在路径和/或在正确的位置。如果你的问题是链接器,你想知道你的二进制文件在寻找哪个路径,你可以用这个命令来找到:
$ readelf -l myapp | grep interpreter
[Requesting program interpreter: /lib/ld-linux.so.2]
如果你的问题是库,命令会给你正在使用的库:
$ readelf -d myapp | grep Shared
$ ldd myapp
这将列出二进制文件需要的库,但您可能已经知道有问题的库,因为它们已经产生错误,就像OP的情况一样。
"patchelf" works for many different problems that you may encounter while trying to run a program, related to these 2 problems. For example, if you get: ELF file OS ABI invalid, it may be fixed by setting a new loader (the --set-interpreter part of the command) as I explain here. Another example is for the problem of getting No such file or directory when you run a file that is there and executable, as exemplified here. In that particular case, OP was missing a link to the loader, but maybe in your case you don't have root access and can't create the link. Setting a new interpreter would solve your problem.
感谢受雇于俄罗斯和Michael Pankov的洞察力和解决方案!
注意分割错误:你可能在myapp使用几个库的情况下,他们中的大多数是可以的,但有些不是;然后你修补它到一个新的目录,你得到分割错误。当你修补你的二进制文件时,你改变了几个库的路径,即使有些原本在不同的路径。看看下面的例子:
$ ldd myapp
./myapp: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by ./myapp)
./myapp: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by ./myapp)
linux-vdso.so.1 => (0x00007fffb167c000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f9a9aad2000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f9a9a8ce000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f9a9a6af000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f9a9a3ab000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9a99fe6000)
/lib64/ld-linux-x86-64.so.2 (0x00007f9a9adeb000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f9a99dcf000)
Note that most libs are in /lib/x86_64-linux-gnu/ but the problematic one (libstdc++.so.6) is on /usr/lib/x86_64-linux-gnu. After I patchelf'ed myapp to point to /path/to/mylibs, I got segmentation fault. For some reason, the libs are not totally compatible with the binary. Since myapp didn't complain about the original libs, I copied them from /lib/x86_64-linux-gnu/ to /path/to/mylibs2, and I also copied libstdc++.so.6 from /path/to/mylibs there. Then I patchelf'ed it to /path/to/mylibs2, and myapp works now. If your binary uses different libs, and you have different versions, it might happen that you can't fix your situation. :( But if it's possible, mixing libs might be the way. It's not ideal, but maybe it will work. Good luck!