一、问题描述
问题:GLIBC 的兼容性问题
环境:Ubuntu20.04 gcc-9 / Ubuntu16.04 gcc-5
错误信息描述:某三方合作公司提供的稀疏化库 sparse.bin 是在 Ubuntu20 中编译的,在低版本服务器中运行出现/lib/x86_64-linux-gnu/libm.so.6: version GLIBC_2.29' not found。
二、解决方案
1. 主要思路:
解决此类问题主要途径有:1. 升级glibc;2. docker 容器;3.通过修改文件的elf强制依赖加载低版本;4.打包原有环境依赖并修改elf依赖。
2. 方案与分析:
方案1 升级 glibc
升级风险较大,而且涉及服务器较多,在docker中尝试了一下升级失败,导致系统命令无法使用;
方案2 docker 容器
同样由于涉及服务器较多,每台 服务器都需要部署docker并迁移数据,工作量仍然比较大;
方案3 修改文件强制降低版本
检查一下程序使用的GLIBC:
objdump -T sparse.bin |grep GLIB
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 localtime
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 atof
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.4 __stack_chk_fail
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 printf
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __libc_start_main
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 time
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 atoi
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.29 exp
0000000000000000 w DF *UND* 0000000000000000 GLIBC_2.2.5 __cxa_finalize
可以看到使用了 exp 计算指令,而目标系统中使用的 glibc 环境最高版本为:
strings /lib/x86_64-linux-gnu/libc.so.6 | grep GLIBC
......
GLIBC_2.22
GLIBC_2.23
GLIBC_PRIVATE
GNU C Library (Ubuntu GLIBC 2.23-0ubuntu11.3) stable release version 2.23, by Roland McGrath et al.
我们可以通过修改EFL符号表来修改依赖,强制将GLIBC_2.29修改为GLIBC_2.23,但是强制修改为低版本依赖,可能发生未知计算错误。
方案4 打包库并修改依赖路径
最终采用了这一方案,我们需要将原环境下依赖打包并修改依赖路径。
三、方案实施
打包代码 tar_lib.sh:
#!/bin/bash
DST_DIR=$PWD"/lib"
BIN_FILE=$1
libs=($(ldd $BIN_FILE | grep -o "/.*" | awk '{print $1}'))
mkdir $DST_DIR
for lib in ${libs[@]}
do
cp "$lib" $DST_DIR
done
可以看到ldd 依赖的库均被打包:
├── ld-linux-x86-64.so.2
├── libc.so.6
└── libm.so.6
将 bin 文件和 libs 拷贝到相应服务器,这时候,需要修改 bin 文件中对库的依赖为 libs 目录,主要方法是用 PatchELF修改依赖,该工具由 NixOS 团队开发,可以直接增加、删除、替换 ELF 文件依赖的库文件。需要修改的主要有2 项:
-
修改可执行程序的动态库搜索路径rpath为当前libs
patchelf --set-rpath `pwd`/libs sparse.bin
-
修改动态库加载器ELF interpreter
patchelf --set-interpreter `pwd`/libs/ld-linux-x86-64.so.2 sparse.bin
四、参考
https://blog.csdn.net/itas109/article/details/106751869
https://zohead.com/archives/mod-elf-glibc/
https://www.cnblogs.com/oloroso/p/12877210.html