环境
# cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)
# strings /usr/lib64/libc.so.6 | grep ^GLIBC_
GLIBC_2.2.5
GLIBC_2.2.6
GLIBC_2.3
GLIBC_2.3.2
GLIBC_2.3.3
GLIBC_2.3.4
GLIBC_2.4
GLIBC_2.5
GLIBC_2.6
GLIBC_2.7
GLIBC_2.8
GLIBC_2.9
GLIBC_2.10
GLIBC_2.11
GLIBC_2.12
GLIBC_2.13
GLIBC_2.14
GLIBC_2.15
GLIBC_2.16
GLIBC_2.17
GLIBC_PRIVATE
GLIBC_PRIVATE
GLIBC_2.8
GLIBC_2.3
GLIBC_2.5
GLIBC_2.4
GLIBC_2.9
GLIBC_2.7
GLIBC_2.6
GLIBC_2.3.2
GLIBC_2.3.4
GLIBC_2.3.3
GLIBC_2.15
GLIBC_2.14
GLIBC_2.11
GLIBC_2.16
GLIBC_2.10
GLIBC_2.17
GLIBC_2.12
GLIBC_2.13
GLIBC_2.2.5
GLIBC_2.2.6
没有
GLIBC_2.18
编译glibc-2.18
curl -O http://ftp.gnu.org/gnu/glibc/glibc-2.18.tar.gz
tar zxf glibc-2.18.tar.gz
cd glibc-2.18/
mkdir build
cd build/
../configure --prefix=/opt/glibc-2.18
make -j2
make install
cd /opt/glibc-2.18/lib
替换libc.so.6
# ln -sf /opt/glibc-2.18/lib/libc-2.18.so /usr/lib64/libc.so.6
# ls
ls: relocation error: /lib64/libpthread.so.0: symbol __getrlimit, version GLIBC_PRIVATE not defined in file libc.so.6 with link time reference
LD_LIBRARY_PATH 未设置, /usr/lib64下的libpthread.so.0版本对不上
# export LD_LIBRARY_PATH=/opt/glibc-2.18/lib:/usr/lib64
# ls
ls: relocation error: /opt/glibc-2.18/lib/libc.so.6: symbol _dl_find_dso_for_object, version GLIBC_PRIVATE not defined in file ld-linux-x86-64.so.2 with link time reference
对应的动态链接库找到了, 但ld-linux.so版本对不上
# ln -sf /opt/glibc-2.18/lib/ld-2.18.so /usr/lib64/ld-linux-x86-64.so.2
Segmentation fault (core dumped)
还是libc.so.6的原因
# LD_PRELOAD=/usr/lib64/libc-2.17.so ln -sf /opt/glibc-2.18/lib/ld-2.18.so /usr/lib64/ld-linux-x86-64.so.2
# ls
bin etc include lib libexec sbin share var
OK
再次确认
# strings /usr/lib64/libc.so.6 | grep ^GLIBC_
GLIBC_2.2.5
GLIBC_2.2.6
GLIBC_2.3
GLIBC_2.3.2
GLIBC_2.3.3
GLIBC_2.3.4
GLIBC_2.4
GLIBC_2.5
GLIBC_2.6
GLIBC_2.7
GLIBC_2.8
GLIBC_2.9
GLIBC_2.10
GLIBC_2.11
GLIBC_2.12
GLIBC_2.13
GLIBC_2.14
GLIBC_2.15
GLIBC_2.16
GLIBC_2.17
GLIBC_2.18
GLIBC_PRIVATE
GLIBC_PRIVATE
GLIBC_2.8
GLIBC_2.3
GLIBC_2.5
GLIBC_2.4
GLIBC_2.9
GLIBC_2.7
GLIBC_2.6
GLIBC_2.3.2
GLIBC_2.3.4
GLIBC_2.3.3
GLIBC_2.18
GLIBC_2.15
GLIBC_2.14
GLIBC_2.11
GLIBC_2.16
GLIBC_2.10
GLIBC_2.17
GLIBC_2.12
GLIBC_2.13
GLIBC_2.2.5
GLIBC_2.2.6
GLIBC_2.18
知识点
- 运行程序时, 系统默认使用的glibc库和动态链接器分别为:
[root@localhost glibc-2.18]# ls -l /usr/lib64/ | grep -E "libc.so|ld-linux"
lrwxrwxrwx. 1 root root 30 May 22 05:58 ld-linux-x86-64.so.2 -> /opt/glibc-2.18/lib/ld-2.18.so
lrwxrwxrwx. 1 root root 32 May 22 05:46 libc.so.6 -> /opt/glibc-2.18/lib/libc-2.18.so
- 链接器加载动态链接库的顺序, 见
man ld.so
When resolving library dependencies, the dynamic linker first inspects each dependency string to see if it contains a slash (this can occur if a library pathname containing slashes was specified at link time). If a slash is found, then the dependency string is interpreted as a (relative or absolute) pathname, and the library is loaded using that pathname.
If a library dependency does not contain a slash, then it is searched for in the following order:
o (ELF only) Using the directories specified in the DT_RPATH dynamic section attribute of the binary if present and DT_RUNPATH attribute does not exist. Use of DT_RPATH is dep-recated.
o Using the environment variable LD_LIBRARY_PATH. Except if the executable is a set-user-ID/set-group-ID binary, in which case it is ignored.
o (ELF only) Using the directories specified in the DT_RUNPATH dynamic section attribute of the binary if present.
o From the cache file /etc/ld.so.cache, which contains a compiled list of candidate libraries previously found in the augmented library path. If, however, the binary was linked with the -z nodeflib linker option, libraries in the default library paths are skipped. Libraries installed in hardware capability directories (see below) are preferred to other libraries.
o In the default path /lib, and then /usr/lib. If the binary was linked with the -z nodeflib linker option, this step is skipped.
- 指定搜索路径
- 在配置文件
/etc/ld.so.conf
中指定动态库搜索路径. 每次编辑完该文件后, 都必须运行命令ldconfig
使修改后的配置生效 ./etc/ld.so.cache
包含了在/etc/ld.so.conf
中指定的目录中查找到所有连接库, 按顺序存储. - 通过环境变量
LD_LIBRARY_PATH
指定动态库搜索路径. - 在编译目标代码时指定该程序的动态库搜索路径. 通过
gcc
的参数-Wl,-rpath
指定. 当指定多个动态库搜索路径时, 路径之间用冒号 ‘:分隔.
-Wl, 表示后面的参数将传给 link 程序
ld(因为
gcc可能会自动调用
ld` ).
- 在配置文件