• 刷新三观的HP-UX系统中的强指针赋值出core问题


           这周在某省升级通信中间件,在RedHat平台的中间件 运行正常,业务可以正常处理。但在 HP-UX服务器上,一承载业务,中间件就出Core重启。

           我立刻组织部门的同事投入到问题分析中。

           首先我在公司的实验室的HP服务器上部署某省的业务。然后在实验室编写votel话务测试脚本,进行业务测试。故障现象浮现,HP下的中间件出core重启。分析代码的位置,是出现在        int i=*(int*)(*begin+1);地方。

            然后对版本进行回滚,原来的代码赋值是

    +   int i;

    +   memcpy((char*)(&i),(*begin)+1,4);

        将该处代码由强指针转换改为memcpy后,业务中间件正常运行。

       对这个问题百思不得其解,于是我安排小汪在写一个简单的测试程序,代码中只写强制转换的代码。

       

    1. #include <stdio.h>
    2. int main()
    3. {
    4. char aa[10] = {'a','b','c','d','d','e','f','a','b','c'};
    5. char *p = (aa+0);
    6. char *p2 = (aa+0);
    7. char **begin = &p2;
    8. printf("%p\n",*begin);
    9. printf("%p\n",*begin+1);
    10. printf("%p\n",**begin);
    11. int functionID = *(int*)(*begin+1);
    12. printf("functionID=%x\n",functionID);
    13. }

      用aCC编译后,运行程序,果然出core。

    然后改用代码

    1. #include <stdio.h>
    2. int main()
    3. {
    4. char aa[10] = {'a','b','c','d','d','e','f','a','b','c'};
    5. char *p = (aa+0);
    6. char *p2 = (aa+0);
    7. char **begin = &p2;
    8. printf("%p\n",*begin);
    9. printf("%p\n",*begin+1);
    10. printf("%p\n",**begin);
    11. int functionID ;
    12. memcpy((char*)&functionID,(*begin)+1,4);
    13. printf("functionID=%x\n",functionID);
    14. }

    aCC编译后运行正常。

    小汪跟我说他看到一个帖子,挺有借鉴意义的,具体如下:

     概括来讲有的CPU存在内存奇偶的机制,要用偶数内存地址做强制转换。

    于是我按照这个文章讲的,对代码又做了修改验证:

    1. #include <stdio.h>
    2. int main()
    3. {
    4. char aa[10] = {'a','b','c','d','d','e','f','a','b','c'};
    5. char *p = (aa+0);
    6. char *p2 = (aa+0);
    7. char **begin = &p2;
    8. printf("%p\n",*begin);
    9. printf("%p\n",*begin+1);
    10. printf("%p\n",**begin);
    11. int functionID = *(int*)(*begin+2);
    12. printf("functionID=%x\n",functionID);
    13. }

    经过aCC编译验证后,程序仍然出core。

    然后我接着进行了修改,具体如下:

    1. #include <stdio.h>
    2. int main()
    3. {
    4. char aa[10] = {'a','b','c','d','d','e','f','a','b','c'};
    5. char *p = (aa+0);
    6. char *p2 = (aa+0);
    7. char **begin = &p2;
    8. printf("%p\n",*begin);
    9. printf("%p\n",*begin+1);
    10. printf("%p\n",**begin);
    11. int functionID = *(int*)(*begin+4);
    12. printf("functionID=%x\n",functionID);
    13. }

    对于指针地址+4后,进行强制转换,用aCC编译后运行,程序可以正常运行。

    然后我把情况给小汪讲了后,小汪又做了个测试:

    1. #include <stdio.h>
    2. int main()
    3. {
    4. char aa[10] = {'a','b','c','d','d','e','f','a','b','c'};
    5. char *p = (aa+0);
    6. char *p2 = (aa+0);
    7. char **begin = &p2;
    8. printf("%p\n",*begin);
    9. printf("%p\n",*begin+1);
    10. printf("%p\n",**begin);
    11. int functionID = *(short*)(*begin+2);
    12. printf("functionID=%x\n",functionID);
    13. }

    用aCC编译后,程序也可以正常运行。

    总结下:

    进行数值进行强转赋值需要谨慎,有的CPU存在内存对齐和起始地址的奇偶性。所以尽量用memcpy(类似memcpy((char*)(&i),(*begin)+1,4);),少用类型强转赋值(类似int i=*(int*)(*begin+1);)。

  • 相关阅读:
    海外数字身份验证服务商ADVANCE.AI入选EqualOcean《2022品牌出海服务市场研究报告》
    魔百和CM311-1A_YST、(YM)_安卓9_S905L3A_默认开启ADB_纯净精简语音_完美线刷包
    Vue2 Element DatePicker组件设置默认日期、控制日期范围
    基于ssm的智慧家政在线预约管理系统的设计与实现-计算机毕业设计源码
    【前端面试题4】
    无用自动化测试?
    JAVA -- 把一个大的sql文件分割成多个小sql文件
    Mac 搭建 Python + selenium自动化测试环境
    C++笔记打卡第22天(仿函数)
    pycharm没有setuptools包、wheel包的解决措施(pycharm添加包的两种方式)
  • 原文地址:https://blog.csdn.net/lzyzuixin/article/details/125443526