问题来源:
记得之前在Ubuntu上更新了gcc后,运行软件时出现了如下报错:
/usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found
这是因为升级gcc时,生成的动态库没有替换老版本gcc的动态库导致的,将gcc最新版本的动态库替换系统中老版本的动态库即可解决:
strings /usr/lib64/libstdc++.so.6|grep GLIBC #用string打印旧版本的gcc的动态库
发现 GLIBCXX最高只到3.4.13 !
mv /usr/lib64/libstdc++.so.6 /usr/lib64/libstdc++.so.6.bak # 先备份旧的
ln -s /usr/local/lib64/libstdc++.so.6 /usr/lib64/libstdc++.so.6 # 建立软连接
OK!成功了!但是前提是你得有sudo权限。
这次,我在服务器上非root条件下进行Pacbio基因组组装时遇到了同样的问题:
/lib64/libc.so.6: version `GLIBC_2.14' not found
我用的软件时Canu1.7,我心想非root我就下载个GLIBC_2.14的库,然后解压缩,编译,再设置动态链接库的环境变量不就ok了么,于是我进行了如下操作
wget -c http://ftp.gnu.org/gnu/glibc/glibc-2.14.tar.xz
mkdir glibc_2.14
./configure —-prefix=/home/path/to/glibc_2.14 # 绝对路径
make -j 8
make install
# 设置环境变量
vim ~/.bashrc
# 将下面加入~/.bashrc的最后
export LD_LIBRARY_PATH=/path/to/glibc-2.14/lib:$LD_LIBRARY_PATH
检查一下:
echo $LD_LIBRARY_PATH
这时候看到动态链接库的环境中已经有了新版的glibc-2.14的lib路径,再次运行软件可以看到之前的报错没有了,但是出现了另外一个问题:软件卡到一半不动了,也没有错误信息。命令行输入java/java -version没有反应。
后来在网上看到别人的文档中写到这种情况与此前更新的GLIBC-2.14有关,于是我重装java,重装glibc-2.14,重新设置环境变量,这样折腾了几十遍(2天)后我看到了这位大神的博客
http://zhuhaidong.win/TP/index.php/Home/Index/article/id/62.html
这种问题称为:
低版本内核下更新GLIBC2.14(libc.so.6)之后,java无法正常运行
其原因归纳为,动态链接库的管理程序ld.so位于/lib/ld-linux-x86-64.so.2路径下,更新GLIBC-2.14后与ld.so版本不兼容,解决方案为:
使用软件PatchELF(https://nixos.org/patchelf.html)改变编译好的二进制文件中对于动态链接库的引用:
./configure --prefix=/home/path/to/software/
make -j 8
make install
patchelf --set-interpreter /home/to/path/software/glibc-2.14/lib/ld-linux-x86-64.so.2 ~/software/jdk1.8.0_191/bin/java
java -version # 发现成功了
原理是改变ld.so的路径,使版本匹配。
解决后就可以开心地再服务器上运行基因组组装软件了。