Linux动态链接库同名符号装载问题(一)

找到了当时发生同名符号冲突的原因。当程序A调用.so模块B时,为了让被调用的B模块能够使用A模块中的一些函数,在编译A程序时使用了--export-dynamic选项。

如果在创建动态链接的可执行文件不加–export-dynamic选项,则它所export的动态符号仅仅包括在链接时动态对象所用到的,因为dlopen是自行加载动态库,并不存在与可执行文件动态符号解析的过程,所以如果dlopen加载的动态库需要了程序中定义的函数,则会出现找不到。

将程序A的符号加入动态符号表后,如果在B模块中出现了与A中符号相同的符号,A的符号优先级较高。比如程序A和.so文件B中各自实现了一个函数do_job_funcB本打算调用自己的do_job_func时,实际调用的是程序A中的do_job_func,出现混乱。

在编译模块B时加上编译选项-fvisibility=hidden后就可以解决冲突的问题。

下面这篇文章详细的解释了--export-dynamic的用途。

http://zhabin.org/2011/01/23/rdynamic/

------------以上2011-9-29更新----------------------------

工作中遇到运行时用dlopen/dlsym加载链接库时发生同名符号冲突导致跳转混乱的问题。

http://blog.csdn.net/zhongyunde/archive/2010/10/14/5939733.aspx

上面这篇博文中提到的方法是用来解决链接时重定位出现的 问题,但是当我使用运行时重定位机制仍然出现了冲突现象,用文中的方法加编译选项-fvisibility=hidden得到解决。但是当我写小程序试图重现,却失败了。困惑中。。。

 -----------以上2011-3-28更新-----------------------------

Linux的动态链接库在链接时,如果在不同模块中出现相同的函数名会发生冲突,导致一个共享对象里面的全局符号被另一个共享对象的同名全局符号覆盖。以下面的例子来说明这一现象:

a1.ca2.c各自实现了一个函数void a(),分别被函数b1和函数b2调用。

 

 

另外有一个main.c,其内部也实现了一个a(),同时他也需要调用b1()和b2()。

 

 

编译并运行:

 

$ gcc -fPIC -shared a1.c -o a1.so 

$ gcc -fPIC -shared a2.c -o a2.so 

$ gcc main.c a1.so a2.so -o main -Xlinker -rpath ./ 

$ ./main

main.c

main.c

 

这与大多数时候我们期待的打印a1.c/na2.c/n不同。

如果我们将main.c改写为下面的,在运行时进行加载,使用dlsym方式调用b1()和b2()

 

 

 

编译并运行,可见已经避免这一问题。

$gcc gcc main.c -o main -ldl

$./main

a1.c

a2.c

 总结:

下一章讲更复杂的情况。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值