Linux 解决 libc.so.6 version GLIBC_2.18 not found 的问题

错误日志信息

1
/lib64/libc.so.6: version 'GLIBC_2.18' not found

系统环境

1
2
CentOS Linux release 7.9.2009 (Core)
Linux 3.10.0-1160.45.1.el7.x86_64 #1 SMP Wed Oct 13 17:20:51 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

查看当前 GLIBC 的版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# strings /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 的版本,可以发现目前系统中最高只支持 GLIBC_2.17,当需要安装依赖 GLIBC_2.18 的软件时,就会出现 libc.so.6: version 'GLIBC_2.18' not found 的错误信息。glibc 是 GNU 发布的 libc 库,即 C 运行库。glibc 是 Linux 系统中最底层的 API,几乎其它任何运行库都会依赖于 glibc。值得一提的是,glibc 除了封装了 Linux 操作系统所提供的系统服务外,它本身也提供了许多其它一些必要功能服务的实现。对于 CentOS 这样的系统,为了追求稳定性(这个值得商榷)往往各种库版本都很低,比如 CentOS 6.5 甚至 CentOS 7.0 自带的还是 glibc 2.12, 而 Ubuntu 14.04 自带 glibc2.19。如果升级 glibc 到一个太新的版本,可能会影响 CentOS 的稳定运行,所以不建议随便升级 glibc 的版本。

解决思路

  • a) 手动编译安装高版本的 gcc
  • b) 在低版本的系统编译自己的软件,前提是自己的软件确实不需要使用新版 GCC 才支持的特性
  • c) 利用容器技术(如 Docker),在低版本的操作系统内,轻量级的隔离出一个虚拟运行环境,适应自己的软件

编译安装 GCC

glibc 的各个版本可以在这里下载。特别注意,在条件允许的情况下,强烈建议在执行下述的 make install 命令之前,全量备份整个 Linux 系统,防止因系统文件意外被破坏,导致系统在启动或运行期间出现崩溃的问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 下载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=/usr --disable-profile --enable-add-ons --with-headers=/usr/include --with-binutils=/usr/bin --enable-checking=release --enable-languages=c,c++

# 编译GCC,指定编译使用的线程数为8,编译耗时较长
# make -j8

# 安装GCC(切记谨慎执行)
# make install

验证 GCC 的版本是否升级成功

如果在下面的输出结果中,出现 GLIBC_2.18,则代表 GCC 的版本升级成功。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# strings /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

或者查看 ldd 的版本

1
2
3
4
5
# ldd --version
ldd (GNU libc) 2.18
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

或者查看系统的库文件

1
2
3
4
5
6
7
8
9
# 查看系统的libc.so库文件
# ls /usr/lib64/libc-*.so -al
-rwxr-xr-x. 1 root root 2156592 10月 14 02:29 /usr/lib64/libc-2.17.so
-rwxr-xr-x. 1 root root 10232696 10月 24 14:52 /usr/lib64/libc-2.18.so

# 查看系统的libc.so库文件
# ls /usr/lib64/libc.so* -al
-rw-r--r--. 1 root root 253 10月 24 14:51 /usr/lib64/libc.so
lrwxrwxrwx. 1 root root 12 10月 24 14:52 /usr/lib64/libc.so.6 -> libc-2.18.so

解决误删 libc.so.6 库文件的问题

在上述的操作中,若误删了 libc.so.6 库文件,会导致系统大多数命令不可用(例如:lscpln)。此时千万不要随便重启系统,缺少 libc.so.6 库文件很容易导致系统无法正常启动,其次也尽量不要关闭正在运行的终端,因为很多东西还可以补救,建议参考以下步骤重新创建 libc.so.6 库文件。

1
2
3
4
5
6
7
8
9
10
11
12
# 查看系统可用的libc库文件
# ls /usr/lib64/libc-*.so -al
-rwxr-xr-x. 1 root root 2156592 10月 14 02:29 /usr/lib64/libc-2.17.so

# 通过系统环境变量LD_PRELOAD导入可用的libc库文件
# export LD_PRELOAD=/usr/lib64/libc-2.17.so

# 利用可用的libc库文件,创建新的libc.so.6库文件
# ln -s -f /usr/lib64/libc-2.17.so /usr/lib64/libc.so.6

# 取消设置系统环境变量LD_PRELOAD
# unset LD_PRELOAD

参考博客