首页 > 系统相关 >Linux多个动态库间的符号冲突问题

Linux多个动态库间的符号冲突问题

时间:2023-09-19 19:15:54浏览次数:45  
标签:product 符号 cJSON ret 库间 skills Linux 字符串 NULL

背景

今天遇到一个奇怪的问题,在客户车机上客户传入json字符串,使用cjson库cJSON_Parse()函数是成功的,但是通过cJSON_GetObjectItem()获取属性却失败了,代码如下

gtc_nlu_product_t* get_product_config(const char* str, gtc_pool_t* pool)
{
    int                    ret;
    gtc_nlu_product_t    * product;
    cJSON                * root, * node, * skills;

    // 初始化
    ret = GTC_OK;
    product = NULL;

    do 
    {
        // 1.解析json
        root = cJSON_Parse(str);
        if (NULL == root)
        {
            ret = GTC_ERROR;
            hloge("product config parse json failed");
            break;
        }

        // 2.提取技能列表
        node = cJSON_GetObjectItem(root, "config");
        if (NULL == node || cJSON_Object != node->type)
        {
            ret = GTC_ERROR;
            hloge("product config get [config] failed");
            break;
        }

        skills = cJSON_GetObjectItem(node, "skills");
        if (NULL == skills || cJSON_Array != skills->type)
        {
            ret = GTC_ERROR;
            hloge("product config get [skills] failed");
            break;
        }

        // 3.分配内存空间
        product = (gtc_nlu_product_t*)gtc_pcalloc(pool, sizeof(gtc_nlu_product_t));
        if (NULL == product)
        {
            ret = GTC_ERROR;
            hloge("alloc memory failed");
            break;
        }

        product->skills = get_product_skills(skills, pool);
        if (NULL == product->skills)
        {
            ret = GTC_ERROR;
            hloge("product config skills empty");
            break;
        }

        // 提取技能领域
        product->aios_domain_list = get_nlu_product_domain_list(product, pool);

    } while (0);

    // 释放资源
    if (root)
    {
        cJSON_Delete(root);
        root = NULL;
    }

    if (ret)
    {
        product = NULL;
    }

    return product;
    
}

 

分析思路

1.怀疑输入字符串有问题,打印输入字符串,字符串是正确的,本地无法复现;
2.怀疑是字符串编码的问题,打印字符串长度,发现字符串长度和字符串完美匹配;
3.怀疑是内存溢出导致cJSON_GetObjectItem()获取属性异常,但是在cJSON_Parse()与cJSON_GetObjectItem()没有任何内存操作;
             考虑是多线程场景,恰好有别的线程操作内存越界,导致当前线程异常,如果是这个原因,没有道理每次都是cJSON_GetObjectItem()获取属性失败,这种巧合接近于0
             考虑是当前线程内业务逻辑有内存操作问题,通过仔细阅读代码,并没有发现内存操作溢出问题
3.仍然不死心,认为是字符串有问题,使用十六进制打印字符串,发现仍然正常;
4.同事反馈如果不判断cJSON对象的类型似乎是可以的,于是我打印出cJSON对象的类型居然是64,这是不符合常理的,

因为CJOSN库中类型的取值范围是[0,6],粗略看了一下代码,似乎也没有啥地方会给类型赋值64,此时我想起来CJSON似乎有高版本,

我手里这个版本好久没有更新了,去官网看了一下CJSON的最新版本,发现CJOSN库中类型取值范围[0,2,4,8,16,32,64],猜测应该是高版本CJSON引发的符号冲突问题;
5.通过nm命令查看动态库,发现动态库确实没有隐藏函数符合,重新出隐藏符号版本,交付验证;
6.最终使用的方案是编译加入-Wl,-Bsymbolic命令,没有验证隐藏符号方案的原因是那是客户的环境,联调比较麻烦,有一个验证OK的就没有继续进行。

小结

在编译动态库的时候,尽量隐藏函数符号,减少动态库间符号冲突问题。

Linux 动态库符号冲突 - 寒魔影 - 博客园 (cnblogs.com)

标签:product,符号,cJSON,ret,库间,skills,Linux,字符串,NULL
From: https://www.cnblogs.com/zhanggaofeng/p/17715516.html

相关文章

  • Linux: Android系统
    Android系统架构Android是谷歌开发的一款基于Linux内核的操作系统。系统架构分为五层,从下到上依次是Linux内核层、硬件抽象层、系统运行库层、应用框架层和应用层。通俗点从下往上依次是:Linuxkernel层,很大一部分内容是驱动程序HAL层,对下封装驱动硬件操作,对上向App提......
  • Linux 最近常用命令汇总
    vi文本替换#全文替换:%s/old/new/g#替换全文第一个匹配项:%s/old/new/#替换当前行所有匹配项:s/old/new/g#替换当前行第一个匹配项:s/old/new/使用crontab配置定时运行脚本#查看所有配置任务crontab-l#修改配置crontab-e除了必要的注释说明文字一......
  • Linux新建免密连接
    1.生成新的密钥对:打开终端窗口,在命令行中输入以下命令:ssh-keygen-trsa-b4096-f~/.ssh/new_key这将生成一个新的4096位的RSA密钥对,并将私钥保存在/.ssh/new_key文件中,公钥保存在/.ssh/new_key.pub文件中。您可以选择不同的文件名和路径。2.将公钥复制到目标主机:使用s......
  • java代码中 两种路径符号的写法
    java代码中两种路径符号的写法Stringpath="D:\\新建文件夹\\2.png"; Filefile=newFile(path); System.out.println(file.exists()); Stringpath1="D:/新建文件夹/2.png"; Filefile1=newFile(path); System.out.println(file1.getAbsolutePath()); Sys......
  • 【linux】WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED 解决方法
    一.错误描述  二.解决方案         输入以下指令:ssh-keygen-RXXX(ip地址)按照我的例子(ip:10.165.7.136),会返回以下信息: 重新尝试连接: 输入yes,按下回车,成功连接。以上就是解决方案,如果想了解为什么这样的,可以继续往下看。三.原因分析当两个设备......
  • Linux 安装守护进程supervisor
    1.使用yum安装yuminstallsupervisor2.开机自启动systemctlenablesupervisord.service3.启动supervisorsystemctlstartsupervisord4.导航至相应目录cd/etc/supervisord.d/5.新建进程文件viApp.ini6.修改进程文件配置如下:[program:App]......
  • 16G内存+CPU本地部署ChatGLM2/Baichuan2推理(Windows/Mac/Linux)
    概述本文使用chatglm.cpp对中文大语言模型(LLM)进行量化与推理,支持ChatGLM2-6B、Baichuan2-13B-Chat等模型在CPU环境16G内存的个人电脑上部署,实现类似ChatGPT的聊天功能。支持的操作系统包括Windows、MacOS、Linux等。其中,量化过程需要临时使用一台内存较大的服务器。4bit量化后......
  • Linux 安装Jenkins
    1.添加yum源sudowget-O/etc/yum.repos.d/jenkins.repohttps://pkg.jenkins.io/redhat-stable/jenkins.repo2.导入密钥sudorpm--importhttps://pkg.jenkins.io/redhat-stable/jenkins.io.key3.安装jenkinsyuminstalljenkins4.修改配置文件vim/etc/sysconfig/jenki......
  • Linux 安装Nodejs
    1.cd/usr/local/src/2.下载nodewgethttps://nodejs.org/dist/v15.4.0/node-v15.4.0-linux-x64.tar.xz3.解压文件tarxfnode-v15.4.0-linux-x64.tar.xz4.导航至解压目录cdnode-v15.4.0-linux-x65.运行node查看版本,确认是否安装成功:./bin/node-v6.设置node软链接:ln......
  • linux单用户模式修改ip
    1、进入GRUB页面,选择对应的内核按下‘e’键;2、进入内核修改信息界面,找到Linux这一行,在这一行的末尾加上single按下ctrl+x进入单用户模式3、输入root密码4、执行“vi/etc/sysconfig/network-scripts/ifcfg-eth0”命令;5、点击i进入编辑模式,修改IPADDR、NETMASK等项的值;6、es......