动态库的GLIBC版本兼容问题

需要将一个jabber的客户端porting到Atom的单板上,遇到的问题如下:

  1. /lib/libc.so.6: version `GLIBC_2.15' not found (required by ./libevent_core-2.0.so.5)
初略分析: libevent_***.so.5是在虚拟机ubuntu12.04上编译的,所以glibc的版本比较高,Atom的Image中glibc的版本比较低;
Google了一圈下来,大致有如下几种解决方法:
1.采用低版本的Glibc重新编译一下代码;(尝试着在本地多装一个Glibc版本,未能成功,有机会可以再try一下;另外装了个fedora12,该版本的Glibc版本与Atom板上接近,但是由于项目还依赖于一些高版本的软件,所以只得放弃)
2.采用全静态方案编译;(网上不少人推崇这种方法,感觉比较坑爹,项目毕竟不是helloworld,不太好全静态编译,改了一天的Makefile,最终以部分底层so,需要挨个下源文件编译而放弃)
3.指定Glibc的版本;

那么主要来介绍一下第三种方法,步骤如下:

1.查看一下具体libevent_****.so.5,是哪些部分调用到了GLIBC_2.15的libc.so.6

  1. objdump -x libevent_****.so |grep 2.15
  2. 0x06969195 0x00 06 GLIBC_2.15
  3. 00000000 F *UND* 00000000 __fdelt_chk@@GLIBC_2.15

通过objdump命令(由于是Atom,所以不需要交叉编译,如果是交叉编译,请注意选用相应的编译器的objdump),可以看出只调用了一个函数__fdel_chk,这时去代码里搜,发现没有该符号;

2.通过反汇编,查找相关的函数调用 

  1. objdump -dS libevent_****.so >dump.txt

去dump.txt中搜索刚才的符号,可以看到 

  1. if (FD_ISSET(i, sop->event_writeset_out))
  2. 1e886: 89 44 24 3c mov %eax,0x3c(%esp)
  3. 1e88a: e8 d1 6c fe ff call 5560 __fdelt_chk@plt

其实__fdelt_chk,是FD_ISSET调用的,由于FD_ISSET是宏,所以之前搜索不到__fdelt_chk.

3.查看Atom单板的GLIBC版本信息 

  1. /lib/libc.so.6

  2. GNU C Library development release version 2.11.90, by Roland McGrath et al.
  3. Copyright (C) 2009 Free Software Foundation, Inc.
  4. This is free software; see the source for copying conditions.
  5. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
  6. PARTICULAR PURPOSE.
  7. Compiled by GNU CC version 4.5.1.
  8. Compiled on a Linux >>2.6.27.41-170.2.117.fc10.i686<< system on 2012-04-17.
  9. Available extensions:
  10.         crypt add-on version 2.1 by Michael Glad and others
  11.         Native POSIX Threads Library by Ulrich Drepper et al
  12.         BIND-8.2.3-T5B
  13. For bug reporting instructions, please see:
  14. <http://www.gnu.org/software/libc/bugs.html>

4.在调用了FD_ISSET的C代码中,指定相应的符号链接Atom单板的GLIBC版本的符号表 

  1. __asm__(".symver __fdelt_chk,__fdelt_chk@GLIBC_2.11")

5.重新编译代码,代码可以成功运行在Atom单板和PC上.

转载请保留地址:http://blog.chinaunix.net/uid-13909379-id-3432236.html

参考链接:

http://www.trevorpounds.com/blog/?p=103

==================================================

#include 
#include 
#include 
 
__asm__(".symver realpath,realpath@GLIBC_2.2.5");
int main()
{
   char* unresolved = "/lib64";
   char  resolved[PATH_MAX+1];
 
   if(!realpath(unresolved, resolved))
      { return 1; }
 
   printf("%s\n", resolved);
 
   return 0;
}

你可能感兴趣的:(深入了解C语言)