• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    linux 下同名符号冲突问题解决方案

    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.重新编译连接三个模块,问题解决。

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

    您可能感兴趣的文章:
    • 解决Linux系统中python matplotlib画图的中文显示问题
    • 基于Linux系统中python matplotlib画图的中文显示问题的解决方法
    • linux下安装nodejs及npm的方法
    • Linux 在Shell脚本中使用函数实例详解
    • linux系统下ubuntu重启apache服务命令
    • VirtualBox安装Archlinux并配置桌面环境
    • linux定时任务访问url实例
    上一篇:linux下tomcat常用操作
    下一篇:Linux启动过程详细介绍
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

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