时间:2021-05-23
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.重新编译连接三个模块,问题解决。
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
先看解决方案#------------mysqlroot用户无法赋权问题解决--------1,登录mysql-uroot-p2,usemysql;选择mysq
问题:使用keep-alive标签后部分安卓机返回缓存页位置不精确问题解决方案:constrouter=newRouter({scrollBehavior(to
gedit中文乱码问题解决,windows下的文档在linux下乱码问题解决:打开终端输入以下命令:复制代码代码如下:gsettingssetorg.gnome
解决方案1:禁用缓存,前一次使用的方法,在电脑上各浏览器都没问题,但在ipad、安卓手机上仍有问题解决方案2:禁用浏览器后退键javascript:window
本文实例讲述了JS中getElementsByClassName与classList兼容性问题解决方案。分享给大家供大家参考,具体如下:document(ele