问题背景:
本地编译的动态共享库(.so)在另外一台服务器上编译链接报错
报错信息如下:
/lib64/libc.so.6: version 'GLIBC_2.14' not found(require ./libsmscrypt.so)
symbol memcpy, version GLIBC_2.14 not defined in file libc.so.6 with link time reference
原因分析:
根据报错信息可以看出so库中memcpy函数使用了高版本的实现,而运行机器上的glibc库中没有相应版本实现,因此需要提供链接低版本glibc库的so库。
分析及解决:
从报错信息可以看出找不到GLIBC_2.14版本的memcpy函数
1、查看libsmscrypt.so中memcpy用的是哪个版本实现$ objdump -T libsmscrypt.so | grep memcpy
可以看出libsmscrypt.so中调用了GLIBC_2.14中的memcpy实现
2、查看系统glibc支持的版本$ strings libc.so.6 | grep GLIBC
3、查看glibc库包含了memcpy的哪些版本
$ objdump -T libc.so.6 | grep memcpy
可以看到本机glibc库提供了2.2.5和2.14版本的memcpy
4、指定libsmscrypt.so中memcpy函数使用2.2.5版本实现
在使用了memcpy的源文件中添加
__asm__(".symver memcpy, memcpy@GLIBC_2.2.5");
5、重新编译生成libsmscrypt.so,查看memcpy使用的版本是否改变
$ objdump -T libsmscrypt.so | grep memcpy
可以看到,memcpy函数使用了2.2.5版本的实现。
完成。
局限性:
__asm__(".symver memcpy, memcpy@GLIBC_2.2.5");
只对一个源文件有效,当多个源文件使用了memcpy,需要在每个文件添加。
示例代码:
//test.c
#include "test1.h"
#include "test2.h"
int main()
{
foo1();
foo2();
return 0;
}
//test1.c
#include "stdlib.h"
#include "string.h"
__asm__(".symver memcpy, memcpy@GLIBC_2.2.5");
void foo1()
{
char *str = "hello world!";
char *t = (char *)malloc(5);
memcpy(t, str, 5);
free(t);
}
//test2.c
#include "stdlib.h"
#include "string.h"
void foo2()
{
char *str = "hello world!";
char *t = (char *)malloc(5);
memcpy(t, str, 5);
free(t);
}
编译:$ gcc test.c test1.c test2.c -o test
查看memcpy依赖的版本:$ objdump -T test
从截图可以看到同时用到了2.2.5和2.14版本的memcpy,说明确实只对一个文件起效。
更通用的实现:
编写一个单独的memcpy.c文件:
#include <string.h>
void *__memcpy_old(void *, const void *, size_t);
asm(".symver __memcpy_old, memcpy@GLIBC_2.2.5");
void *__wrap_memcpy(void *dest, const void *src, size_t n)
{
return __memcpy_old(dest, src, n);
}
将test1.c中的__asm__(".symver memcpy, memcpy@GLIBC_2.2.5");
去掉
编译:$ gcc test.c test1.c test2.c memcpy.c -Wl,--wrap=memcpy -o test
gcc编译时使用 -Wl,--wrap=memcpy选项,使得链接器将memcpy解析为__wrap_memcpy。
查看:$ objdump -T test
可以看到memcpy现在只依赖2.2.5版本的实现
参考:
http://b.liuctic.com/2013/11/glibc_2-14-%E5%85%BC%E5%AE%B9%E9%97%AE%E9%A2%98-lib64libc-so-6-version-glibc_2-14-not-found/
glibc和Symbol Versioning和如何链接出低版本glibc可运行的程序 · BlahGeek's Blog
version `GLIBC_2.14' not found 解决方法._功名半纸的博客-CSDN博客