知识点四:
我们也可以看看我们的机器上所有的libc.so.6的版本: 用locate命令来定位
www.linuxidc.com@linuxidc:/lib/x86_64-linux-gnu$ locate libc.so.6
/lib/x86_64-linux-gnu/libc.so.6
/lib32/libc.so.6
lib32下的libc.so.6也是NPTL版本。我的机器上已经找不到linuxthreads版本了。呵呵,现在的Ubuntu的Linux内核早就是2.6的了。
知识点五:
什么是ABI?其实ABI就是系统调用加用户可以直接使用的ISA. 所以ABI版本和编译器以及系统库有关。
动态库(共享库,*.so)可以告知动态链接器它能够正常运行所必需的最低的操作系统的应用程序二进制接口(ABI)版本。
动态库的ELF格式里面有一个Note section
我们可以读到它,一般的readelf还不行,要先安装elfutils.
www.linuxidc.com@linuxidc:sudo aptitude install elfutils
装好后,我们读取ELF里面的NOTE SECTION
-n 就是显示elf notes
www.linuxidc.com@linuxidc:/lib/x86_64-linux-gnu$ eu-readelf -n libc-2.13.so
Note section [ 1] '.note.gnu.build-id' of 36 bytes at offset 0x270:
Owner Data size Type
GNU 20 GNU_BUILD_ID
Build ID: 73c3b573c5907f908727dd0484a7e0122c3bd6ab
Note section [ 2] '.note.ABI-tag' of 32 bytes at offset 0x294:
Owner Data size Type
GNU 16 VERSION
OS: Linux, ABI: 2.6.15
我们再次看到这个动态库需要 OS: Linux, ABI: 2.6.15。
程序运行时,动态链接器会根据最近的动态库查找路径并依次查找。它会链接找到第一个满足最低ABI版本要求的库,或者无法找到满足最低ABI版本的库,链接失败并终止程序。
设置LD_ASSUME_KERNEL低于任何glibc动态库版本的最低要求的ABI版本,这样链接器将跳过该glibc库,并尝试找到一个比该版本更旧的线程实现的glibc库。
我们可以设置该环境变量,假定当前操作系统是一个特定的ABI /内核版本。这样可以达到跳过默认顺序链接的线实现 ,而使用特定版本库的线程实现。
$ export LD_ASSUME_KERNEL=X.Y.Z
列如:
由于Oracle 9i FOR LINUX是在标准的linux Threads下开发的,因此当在RedHat(kernel 2.6)linux上安装的时候,必须设定LD_ASSUME_KERNEL为2.4.0,以让redhat linux使用标准的linux Threads, 否则安装进度指示条一直停留在开始处,如:RHAS 4,RHEL 5.
当然这需要你机器上有这个版本的GLIBC.我机器上就没有。