如果将glibc2.12 暴力降级到 glibc2.9 ,会发生什么?
本座以前没有这么试验过 ,这几天试验了一把。由于出现了乐观的结果 ,所以本座在这里乐观地写了这篇博客。
省略掉很多字,反正本座将glibc降级的原因就是怀疑它的这个版本有问题,是跟“invalid fastbin entry”相关的一个问题。本座用的glibc版本是2.12.1,在网上搜索的时候发现别人也碰到这样的问题了,向Fedora项目提交bug之后还真的被证实了,只不过别人的版本是2.11而已。也许2.12还是没有彻底解决这个问题呢。另外呢,这个程序在其它的三台使用glibc2.9的机器上从12月19号到现在都在一直运行呢,没有崩溃。所以本座决定对这个如此核心的库进行一番怀疑,降级到glibc2.9进行测试。
一开始,本座将glibc2.9的源代码编译安装,在编译的时候出错了,是在sysdep.h文件中,这个错误上网去能查到,是跟gcc有关的,按照网上说的方法修改一下sysdep.h文件就行了。再编译,成功了。再安装。再把ldconfig运行了一次。本座本来以为这样glibc2.9就在系统里面替换掉了glibc2.12了,并且预期会有很多程序运行不正常。结果呢,没看到不正常运行的程序,本座还一阵高兴呢。反正不管那么多,将自己的程序重新编译一次,再运行起来测试了。
直到程序再次 “invalid fastbin entry”的时候,本座终于觉得 ,是不是本座并没有成功地把 glibc2.9 安装上去呢?看看程序到底在用哪个共享库吧 。
使用 ldd 查看了一下本座的程序所链接到的库 , 其中的一条是 /lib/libc.so.6 ,从名字就能猜出来这个是 glibc 的共享库了 ,看看它的修改日期就知道到底是本座新安装上去的 glibc2.9 还是原来安装的 glibc2.12 了 。本座进入 /lib 目录一看 ,发现 /lib/libc.so.6 原来只是一个链接 ,并且当前是链接到 /lib/libc-2.12.so ,在目录中还另外有一个 libc-2.9.so 。原来是这样的啊,本座安装上去的 glibc2.9 只是被放到了库目录中,却没有被链接使用。这可能是某种版本控制机制吧 ,只链接到高版本的库。
为了继续测试 ,本座做了一番心理准备之后 ,开始 改动链接了 。根据 ldd 命令输出的结果,看看本座的程序所链接的库中,有哪些是由 glibc 提供的,都改成对应的 2.9 版本。到时候再根据系统报告的错误来判断还有哪些其它的库文件的链接要改动 。
•. 将/lib/libpthread.so.0链接到/lib/libpthread-2.9.so
•. 将/lib/libc.so.6链接到/lib/libc-2.9.so
•. 将/lib/ld-linux.so.2链接到/lib/ld-2.9.so
•. 将/lib/libdl.so.2链接到/lib/libdl-2.9.so
本座的程序所依赖的 glibc 的库文件就只有上面那么多了。由于不清楚还有哪些库要改动链接,所以只改动上面这些库的链接。
另外,将这个列表保存到硬盘上的文件里,如果系统出现其它问题则按照这个列表恢复。注意用来保存这个记录的文件要用英文名 ,包括所在的整个路径中的目录都要用英文名,因为,如果真的出了问题,还不能保证系统能不能识别中文呢。
改动之后,报告 libm.so.6 的ABI不兼容,经过检查,发现 libm.so.6 也是 glibc 中的库,所以也要改动它的链接。
•.将/lib/libm.so.6链接到/lib/libm-2.9.so
改动之后,本座的程序运行起来了。
改动之后,网络管理器出错,连不上网了。而本座的程序需要进行网络通信 ,所以还要把网络弄好啊。
报告 /lib/libresolv.so.2 的ABI不兼容。经过检查,这也是 glibc 中的库,因此也改动链接。
•.将/lib/libresolv.so.2链接到/lib/libresolv-2.9.so
再次运行,报告 /lib/librt.so.1 的ABI不兼容。这也是 glibc 中的库,因此也要改动链接。
•.将/lib/librt.so.1链接到/lib/librt-2.9.so
运行 dhclient 给网卡获取IP时,报告 /lib/libcrypto.so.8 的ABI不兼容。这是 OpenSsl 中的库,是较新版本的,可能是与 glibc2.9 不兼容。因此尝试从其它机器将对应的库文件复制过来。
从局域网的一台机器上复制 /lib/libcrypto.so.0.9.8e (在这个时候,网卡可以配上IP,并且能与局域网内的机器通信,但是好像处于一种“down”的状态)。
•.将/lib/libcrypto.so.8链接到/lib/libcrypto.so.0.9.8e,注意原来是链接到/usr/lib/libcrypto.so.0.9.8l的
成功连上网了。现在就等着看本座的程序还会不会崩溃了。
另外 ,很快就发现其它的好多程序 都运行得不正常了,大多数是运行不起来的 ,一般是报告这个库或者那个库的ABI不兼容 。这个时候 ,就见机行事了,根据错误情况判断 该给哪个库也降降级。这个过程中 ,本座还用上了 strace 工具,虽然对这个工具不怎么会用。因为有些程序在运行的时候不会报告哪个库的 ABI不兼容,它只会报告一句不容易看懂的错误之后退出 。对这些程序,用 strace 跟踪执行过程 ,看看它们在打开哪些库文件并且尝试引入的时候出错 ,基本就能判断出是跟什么库有关了 。
到本座写这 篇文章的时候, OpenOffice.org 已经能运行了 ,因为本座这篇文章就是用 OpenOffice.org 写的。其它的大部分程序也运行起来了 ,比如 Chmsee 、 Dolphin 、 Ddevelop 、 Konsole 、 QtCreator 、 ThunderBird ,满足本座的基本应用已经可以了 。
所以到这个时候 ,本座终于把 glibc 暴力降级了 ,本座只有一个感觉,就是“刺激” 。系统里面还有很多其它的程序呢,本座时刻准备着它们告诉本座 “某某库不兼容”。
虽然这 篇文章看起来很轻松 ,但是本座对于将 glibc 降级这件事没有完善的解决方案 ,如果你想尝试,那么你自己小心行事吧 。 glibc2.12 中的共享库一般都是 glibc2.9 中的共享库的5倍左右的大小 ,比如说 libc-2.12.so 有8.5M,而 libc-2.9.so 只有1.5M,这7M的大小不是随便多出来的 , glibc2.12 一定与 glibc2.9 有很多不同。在动手做这种事情之前 ,要做好心理准备 。
HxLauncher: Launch Android applications by voice commands