文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

linux 下同名符号冲突问题解决方案

2022-06-04 21:50

关注

linux 下同名符号冲突问题解决方案

最近的工作中遇到如下令人蛋疼的问题:

Linux 下有三个模块aa、bb、cc,基本情况如下:

cc 编译连接得到 cc.so 动态库,cc 中有如下接口:


cc_fun 
{ 
…… 
do();//调用名为do的cc模块内部函数 
…… 
} 
 

bb 编译连接得到 bb.a 静态库,bb 中有如下接口:


bb_fun 
{ 
…… 
handle = dlopen(cc.so, RTLD_LAZY);//加载cc.so 
pccfun = dlsym(handle, “cc_fun”);//获取cc_fun函数指针 
(*pccfun)();//调用cc_fun函数,此时应该会调用cc模块中的do()函数 
do();//调用名为do的bb模块内部函数(与cc模块中的do()函数同名,实现却不相同) 
…… 
} 

aa 编译后通过 -lbb 链接选项的方式连接 bb.a 得到 aa 可执行程序,并调用 bb.a 的接口函数 bb_fun():


main 
{ 
…… 
bb_fun();//调用bb_fun函数 
…… 
} 
 

工作中发现 aa 在运行时行为异常,总是有内存泄露和功能异常,通过定位发现问题集中在同名的 do() 函数上。通过输出打印发现程序中两次调用 do() 函数都调用到了 bb 模块中的 do() 函数,而 cc 模块中的 do() 函数从未被调用到,导致程序行为异常和内存泄露。

后经多方查证了解到因为 linux 程序中各个库中的符号表最终都会加载到程序所在的全局符号表中,此时如果有同名符号就只能调用到第一个加载进来的符号,也就是说后边加载的同名符号都会被之前的覆盖。cc 模块中的 do() 函数被 bb 模块中的 do() 函数覆盖了,所以无法被调用到。

废话不多说。。。

在试验过很多不满意的方法之后,最终的解决方法如下:

1.在 cc 的 makefile 中加入 -Wl,-Bsymbolic -Wl,--version-script,version 的连接选项,意思是用 version 文件中的脚本指定其导出哪些函数。

2.version 文件的实现如下:


VERS{ 
global: 
cc_fun; 
local: *; 
}; 

意思是指定 cc 模块只导出接口函数 cc_fun,其余函数都设为 local 不做导出。

将该文件保存在 makefile 所在目录即可。

3.重新编译连接三个模块,问题解决。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-人工智能
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯